mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
1. https://github.com/bvaughn/react/commit/9fc04eaf3fb701cdc14f57d5aed48f3126af6c94#diff-2c5e1f5e80e74154e65b2813cf1c3638f85034530e99dae24809ab4ad70d0143 introduced a vulnerability: we listen to `'fetch-file-with-cache'` event from `window` to fetch sources of the file, in which we want to parse hook names. We send this event via `window`, which means any page can also use this and manipulate the extension to perform some `fetch()` calls. With these changes, instead of transporting message via `window`, we have a distinct content script, which is responsible for fetching sources. It is notified via `chrome.runtime.sendMessage` api, so it can't be manipulated. 2. Consistent structure of messages `{source: string, payload: object}` in different parts of the extension 3. Added some wrappers around `chrome.scripting.executeScript` API in `packages/react-devtools-extensions/src/background/executeScript.js`, which support custom flow for Firefox, to simulate support of `ExecutionWorld.MAIN`.
104 lines
2.6 KiB
JavaScript
104 lines
2.6 KiB
JavaScript
/* global chrome */
|
|
|
|
import setExtensionIconAndPopup from './setExtensionIconAndPopup';
|
|
import {executeScriptInMainWorld} from './executeScript';
|
|
|
|
import {EXTENSION_CONTAINED_VERSIONS} from '../utils';
|
|
|
|
export function handleReactDevToolsHookMessage(message, sender) {
|
|
const {payload} = message;
|
|
|
|
switch (payload?.type) {
|
|
case 'react-renderer-attached': {
|
|
setExtensionIconAndPopup(payload.reactBuildType, sender.tab.id);
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
export function handleBackendManagerMessage(message, sender) {
|
|
const {payload} = message;
|
|
|
|
switch (payload?.type) {
|
|
case 'require-backends': {
|
|
payload.versions.forEach(version => {
|
|
if (EXTENSION_CONTAINED_VERSIONS.includes(version)) {
|
|
executeScriptInMainWorld({
|
|
target: {tabId: sender.tab.id},
|
|
files: [`/build/react_devtools_backend_${version}.js`],
|
|
});
|
|
}
|
|
});
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
export function handleDevToolsPageMessage(message) {
|
|
const {payload} = message;
|
|
|
|
switch (payload?.type) {
|
|
// Proxy this message from DevTools page to content script via chrome.tabs.sendMessage
|
|
case 'fetch-file-with-cache': {
|
|
const {
|
|
payload: {tabId, url},
|
|
} = message;
|
|
|
|
if (!tabId) {
|
|
throw new Error("Couldn't fetch file sources: tabId not specified");
|
|
}
|
|
|
|
if (!url) {
|
|
throw new Error("Couldn't fetch file sources: url not specified");
|
|
}
|
|
|
|
chrome.tabs.sendMessage(tabId, {
|
|
source: 'devtools-page',
|
|
payload: {
|
|
type: 'fetch-file-with-cache',
|
|
url,
|
|
},
|
|
});
|
|
|
|
break;
|
|
}
|
|
|
|
case 'inject-backend-manager': {
|
|
const {
|
|
payload: {tabId},
|
|
} = message;
|
|
|
|
if (!tabId) {
|
|
throw new Error("Couldn't inject backend manager: tabId not specified");
|
|
}
|
|
|
|
executeScriptInMainWorld({
|
|
target: {tabId},
|
|
files: ['/build/backendManager.js'],
|
|
});
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
export function handleFetchResourceContentScriptMessage(message) {
|
|
const {payload} = message;
|
|
|
|
switch (payload?.type) {
|
|
case 'fetch-file-with-cache-complete':
|
|
case 'fetch-file-with-cache-error':
|
|
// Forward the result of fetch-in-page requests back to the DevTools page.
|
|
// We switch the source here because of inconsistency between Firefox and Chrome
|
|
// In Chromium this message will be propagated from content script to DevTools page
|
|
// For Firefox, only background script will get this message, so we need to forward it to DevTools page
|
|
chrome.runtime.sendMessage({
|
|
source: 'react-devtools-background',
|
|
payload,
|
|
});
|
|
break;
|
|
}
|
|
}
|