Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update conditional content script injection to use faster methods #1865

Open
alexristich opened this issue Feb 12, 2018 · 6 comments
Open

Update conditional content script injection to use faster methods #1865

alexristich opened this issue Feb 12, 2018 · 6 comments
Assignees
Labels
enhancement Firefox MV3 Manifest V3-specific issue question Further information is requested

Comments

@alexristich
Copy link
Contributor

Currently we inject content scripts conditionally with message passing, where the content script will query the background page as to whether it should inject itself into the page. This has the potential for the content script to be injected after a page script has already executed. In the case of fingerprinting.js, this means we may not catch an instance of fingerprinting because the fingerprinting occurred before our content script was run.

Mozilla has released a new API (https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/contentScripts/register) which looks promising. It currently only works for Firefox 59+.

Another alternative is tabs.executeScript() (https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/tabs/executeScript), which may provide faster injection of content scripts than our current message passing approach.

A final(?) contender is webNavigation.onCommitted (https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/webNavigation/onCommitted), which, according to Adguard is the fastest means of conditionally injecting a content script: gorhill/uBlock#1930 (comment)

@ghostwords
Copy link
Member

Related to gbaptista/luminous#55. I'm also reviewing these as part of #1861.

@ghostwords
Copy link
Member

I am using this fixture for testing. It comes with an inline script that prints the value of navigator.doNotTrack. Since it's a tiny inline script, anything asynchronous fails to run in time to change its output. If you open the developer console, you'll see the page also continuously prints the value of navigator.doNotTrack every millisecond until it becomes either "1" or "0", which helps you see what your injection delay is.

@alexristich
Copy link
Contributor Author

alexristich commented Feb 18, 2018

I just pushed a work-in-progress using the contentScripts API. A few things to note:

  1. This code currently does not work on Chrome.
  2. In having conditional injection in Firefox 59+, we by necessity need to have conditional injection in Chrome as well, as we can no longer list the specified content scripts in manifest.json.
  3. For some reason, "<all_urls"> is not permitted to be used in the matches key when registering the content scripts. I'll file a Bugzilla issue on this soon.
  4. I think passing standardized configuration objects will be challenging for certain scripts. In supercookie.js we have a checkEnabledAndThirdParty query. Checking the enabled state is easy with the contentScripts.register() way of injecting things, given we can check for the absence of a property in the configuration object - this would indicate the script was injected with the contentScripts API. However, determining whether something is third-party wouldn't be possible without receiving some context from the background page. Given this, I believe we would still need to engage message passing in some cases.

I think the next steps are to (a) decide on which approach, tabs.executeScript() or webNavigation.onCommitted(), should be used for conditional injection in browsers that don't yet support the contentScripts API, and (b) figure out a reasonable way to pass configuration to the content scripts. I think the answer for (b) might lie in sending the code as a code string and appending the configuration. Here's some interesting thoughts on this problem in any case: https://stackoverflow.com/a/40815514

@alexristich
Copy link
Contributor Author

Bug for tracking the second point listed in my comment above:
https://bugzilla.mozilla.org/show_bug.cgi?id=1439814

@alexristich
Copy link
Contributor Author

Following up on this issue, the current issue presented here is the "slow" conditional injection of content scripts. The reason for this "slowness" is that the content scripts need to know whether they should inject themselves into the page. A case where a content script should not inject itself is when the current site is whitelisted by the user.

The way this is currently achieved is using synchronous message passing with chrome.runtime.sendMessage. The proposed solutions above aim to address this, though the optimal solution is to use the new browser.contentScripts API. However, this API is currently only supported in Firefox 59+.

In order to fully leverage this new API, we must either (a) adjust how all current content scripts are declared and injected to avoid duplicate injection, or (b) duplicate all the current scripts, making necessary tweaks to support both methods and avoiding duplicate injection.

Both of these approaches have downsides, though given the limitations presented to content scripts and the requirements of our content scripts (i.e. injected as close to document_start as possible), there doesn't appear to be much room if any for flexibility outside these two options.

@fregante
Copy link

fregante commented Jul 1, 2019

I just pushed a work-in-progress using the contentScripts API. A few things to note:

  1. This code currently does not work on Chrome.

You can use the Chrome polyfill for contentScripts.register. If there's interest it can probably be adjusted to work in Firefox 58- (but it might already work there as is)

@ghostwords ghostwords added the question Further information is requested label Nov 10, 2020
@ghostwords ghostwords added the MV3 Manifest V3-specific issue label Jul 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Firefox MV3 Manifest V3-specific issue question Further information is requested
3 participants