CWE-79 (XSS) and CWE-653 (Insufficient Compartmentalization) both apply when content scripts run in the MAIN world. A content script in the MAIN world shares the JavaScript heap with the host page — the page's JavaScript can read and modify the extension's variables, and vice versa. A compromised or malicious page can tamper with the extension's logic directly, override its functions, or read any data it has loaded. OWASP A03 (Injection) governs this. Chrome's ISOLATED world is the default for a reason: it creates a separate JavaScript environment, preventing the host page from accessing or polluting the extension's execution context. The Chrome content script documentation makes this the required default.
High because running in the MAIN world removes the JavaScript heap boundary between the extension and the host page, allowing the page to directly manipulate extension state and bypass isolation.
Remove any world: "MAIN" declarations from your content_scripts entries in manifest.json. Omitting the world property defaults to ISOLATED, which is correct.
{
"content_scripts": [{
"matches": ["https://example.com/*"],
"js": ["content.js"]
}]
}
If you need to expose a function to the page's JavaScript, use window.postMessage from the isolated content script — the page sends a message, the content script receives and validates it, then responds.
ID: extension-permissions-security.content-script-isolation.isolated-world
Severity: high
What to look for: Enumerate all content_scripts entries in manifest.json. For each, check the world property. In MV3, world can be "ISOLATED" (default) or "MAIN". Count the number of scripts using "MAIN" world.
Pass criteria: At least 100% of content scripts run in the ISOLATED world (property omitted defaults to isolated, which counts). No more than 0 scripts use world: "MAIN" without documented justification. Quote the world configuration for each content script entry.
Fail criteria: world: "MAIN" is used without extremely strong justification.
Skip (N/A) when: No content scripts defined in manifest.
Detail on fail: "Content script is configured to run in the MAIN world. It shares the same execution environment as the page, making it vulnerable to conflict and manipulation."
Remediation: Always use the isolated world in manifest.json unless you are building a specific tool that requires modifying the page's global JS variables (rare). If you need to expose APIs to the page, use window.postMessage.
{ "content_scripts": [{ "matches": ["https://example.com/*"], "js": ["content.js"] }] }