react icon indicating copy to clipboard operation
react copied to clipboard

[DevTools] Fix developer tools not working in tabs restricted by CSP

Open mochiya98 opened this issue 4 weeks ago • 1 comments

Summary

fix #34268, close #29647 (duplicated)

The current implementation uses chrome.devtools.inspectedWindow.eval() , which can be blocked by a page's Content Security Policy (CSP). To handle this, I implemented a fallback mechanism that, if eval fails, attempts to evaluate the code in a Content Script.

Because Content Scripts do not have access to the Developer Tools Console API (e.g., inspect(), $0), some features (e.g. focusing a specified DOM node in the Elements panel) will remain unavailable.
However, this change still improves a situation where developer tools were completely unusable and will make many features available.

How to test

Please follow the reproduction steps from the original issue (#34268) to test behavior.

Note: when you reload the extension, tabs that were already open may not behave correctly. After loading the extension, open a new tab to test.

Detailed flow of operations

sequenceDiagram
    participant DevTools as DevTools Page<br>(main/index.js)
    participant Background as Background Script<br>(background/messageHandlers.js)
    participant CS as Content Script<br>[ExecutionWorld.ISOLATE]<br>(contentScripts/proxy.js)
    participant Page as Content Script<br>[ExecutionWorld.MAIN]<br>(contentScripts/fallbackEvalContext.js)
    
    alt First, attempt the regular processing
        DevTools->>DevTools: chrome.devtools.inspectedWindow.eval()
    else If it fails due to an error, run the fallback process below. (e.g. CSP Blocked)
        
        Note right of DevTools: Message:<br>{ source: 'devtools-page', payload: {<br>type: 'eval-in-inspected-window',<br>tabId, requestId, scriptId, args, } }
        DevTools->>Background: chrome.runtime.sendMessage()
        
        Note right of Background: Message:<br>{source: 'devtools-page-eval',<br>payload: { scriptId, args, } }
        Background->>CS: chrome.tabs.sendMessage()
        
        Note right of CS: Message:<br>{ source: 'react-devtools-<br>content-script-eval',<br>payload: { requestId, scriptId, args, } }
        CS->>Page: window.postMessage()
        
        Note over Page: Eval in Content Script<br>evalScripts[scriptId].apply(null, args);
        
        Note right of CS: Message:<br>{ source: 'react-devtools-<br>content-script-eval-response',<br>payload: { requestId, response, } }
        Page-->>CS: window.postMessage(Response)
        Note right of Background: Message:<br> response ( {result, error} )
        CS-->>Background: sendResponse()
        Note right of DevTools: { source: 'react-devtools-background',<br>payload: { type: 'eval-in-inspected-<br>window-response',<br>requestId, result, error, } }
        Background-->>DevTools: chrome.runtime.sendMessage()
    end

mochiya98 avatar Nov 25 '25 12:11 mochiya98

Thank you.

That certainly seems like a good improvement. I consolidated all eval processing into src/evalScripts.js, updated the callers, and added the license header and Flow definitions.

mochiya98 avatar Nov 26 '25 15:11 mochiya98

@eps1lon @hoxyq +1 on this. We can't use DevTools at all in our CSP-restricted environment. This would be a significant improvement for enterprise users. Is there anything blocking this?

rearchitec avatar Dec 10 '25 07:12 rearchitec