w3c / webextensions

Charter and administrivia for the WebExtensions Community Group (WECG)
Other
591 stars 54 forks source link

Inconsistency: CSP sandbox directive and content script and style injection into pages #285

Open bershanskiy opened 1 year ago

bershanskiy commented 1 year ago

Chrome injects content scripts and styles into contexts with CSP directive sandbox, while Firefox and Safari do not.

Philosophically, since typically extension resources are exempt from other CSP directives like script-src, style-src, and other, browsers should exempt extension resources from sandbox as well. However, two browsers have this "bug" and only one is "correct", which is not typical.

Testing details

Real-world URL

This issue was initially discovered on the following URL: https://ci.ubports.com/job/docs.ubports.com/job/PR-508/7/artifact/_build/html/..index.html

This originally came up at: https://github.com/darkreader/darkreader/issues/9861

Minimal demo

Chrome

When a tab is opened, it shows only red Script ran text. Text comes from script, while red color comes from injected style.

Safari and Firefox

Extension has no effect on the tab.

Code

NodeJS Express server:

'use strict';

const express = require('express');

const app = express();

app.get('/index.html', (req, res) => {
  res.set('content-security-policy', 'sandbox');
  res.send('Hello world!');
});

app.listen(8000);

Extension manifest.json:

{
  "manifest_version": 2,
  "name": "Demo",
  "description": "Demo",
  "version": "1.0",
  "content_scripts": [
    {
      "matches": ["*://*/*"],
      "js": ["script.js"],
      "css": ["style.css"]
    }
  ]
}

Extension content script script.js:

document.body.innerText = 'Script ran';

Extension injected style style.css:

body {
  color: red;
 }
Rob--W commented 1 year ago

FYI: this issue is known and I have co-designed an API with Chrome to control the behavior in a predictable way. Details are linked from https://bugzilla.mozilla.org/show_bug.cgi?id=1411641#c43

Firefox has not implemented it yet (but it's tracked in that bug).

Chrome has implemented it in (again detail in the bugs linked from the bug):

tophf commented 1 year ago

NOT in tabs.executeScript nor in scripting.executeScript

AFAICT from the source code, scripting.executeScript always uses matchOriginAsFallback mode.

Rob--W commented 3 months ago

I have recently implemented support for content script injection in sandboxed documents, and match_origin_as_fallback to match about:blank, about:srcdoc, data: and blob: in Firefox 128.

In cases where the URL contains a meaningful representation of the document, i.e. http(s) and file:-schemes, we use that URL for matching. Even if the origin is opaque due to the use of CSP sandbox by the web page.

match_origin_as_fallback supersedes match_about_blank:

oliverdunk commented 3 months ago

match_origin_as_fallback and associated sandboxed document behavior is already supported in Chrome :)