w3c/webextensions

Use cases and features for registerContentScripts() (early conf, parameters, WorkerScope injection, tab filtering, CSP)

hackademix opened this issue · 2 comments

The chrome.scripting.registerContentScripts API (documention still referring to an in-progress snapshot) is very promising as a potential solution to multiple problems which we've been barely able to address in MV2 only by using several hacks.

Sice these hacks are going to be forbidden/impossible in MV3, it's even more crucial for this API to do the right things and serve the real world use cases.

Here we summarize the most prominent use cases and issues (some acknowledged by Chromium developers and promised to be addressed, some whose status is still unclear) as collected in the Chromium tracking issue:

  1. Early injection AND configuration, to avoid race conditions which affect MV3 content scripts. This should be addressed by honoring runAt: "document_start" (which is already there) but requires also n. 2 and n. 3 below.
  2. Dynamic configuration parameters: since the new API doesn't allow the injected script to be arbitrary strings built at runtime, a way to configure them dynamically (changing the parameters for each RegisteredContentScript object) is indispensable. Passing a JSON object which would populate the execution context with variables named after its top level properties would be a way, but others equivalent options may work.
  3. Per-tab filtering (which is not there yet, but has been promised), in order to turn on/off features per tab. Notice that the ability of accessing the tabId from the injected script might help, moving the responsibility for filtering in the script itself, BUT would require n.2 to pass down the global tab filter settings and the tabId access to be synchronous, in order to guarantee n. 1.
  4. WorkerScope injection - main world scripts should be able to modify JavaScript-accessible object (e.g. DOM prototypes or built-in functions) in a way that is transparent and cannot be subverted by page scripts. This obviously requires n. 1, but also the ability to inject WorkerScope(s), to prevent the "native" behavior or data which we want to patch from being restored by page's scripts through workers (e.g., beside the obvious built-ins like Date, workers expose also OffscreenCanvas, which many extensions patching Canvas for privacy reasons would need to patch as well).
  5. CSP immunity - world-injected scripts must be able to work around CSP restrictions on script execution (see https://bugzilla.mozilla.org/show_bug.cgi?id=1267027, https://bugs.chromium.org/p/chromium/issues/detail?id=1137396 and https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Sharing_objects_with_page_scripts for a glance on the cross-browser confusion which currently affects this important topic).

Probably related (absorbed by this one): issue #85

Both this and #314 have been discussed in meetings more than one year ago, but even though in those occasions browser vendors signaled good will and support, no progress has been made.

The bare minimum (which would incidentally fix/work around other more recent issues like #513 would be:

  1. An args+func properties pair (analogous to ScriptInjection) in RegisteredContentScript in order to reliably parametrize document_start scripts at the right time and avoid races with page-provided scripts.
  2. A RegisteredContentScript.workers boolean property analogous to the one mentioned in #306 (originally under the misguided/obsolete assumption that InjectionTarget and ScriptInjection would eventually be included as RegisteredContentScript property types)
  3. (Optional) having Firefox implement RegisteredContentScript.world, or clearly document how to safely interact with the main world especially to modify / proxy DOM and JavaScript prototypes, also in case of WorkerScope injection.

Hope to have this (re)discussed in next meeting, thanks.

As discussed in today's meeting, I've opened separate proposal issues for each feature to be added in scripting.registerContentScript()

I've left out the MAIN world execution support in Firefox because is already tracked by https://bugzilla.mozilla.org/show_bug.cgi?id=1736575