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

Firefox User Scripts API #604

Open
bershanskiy opened this issue Sep 4, 2019 · 16 comments
Open

Firefox User Scripts API #604

bershanskiy opened this issue Sep 4, 2019 · 16 comments

Comments

@bershanskiy
Copy link

Firefox recently introduced two new APIs for WebExtensions, called Content Script API and User Script API. The APIs are supposed to replace the current methods of injecting remote code (code not available in the extension when it is submitted to the Firefox Add-ons store). The current methods of injecting remote code (e.g., eval() and creating <script> tag and inserting code into it) will be deprecated and removed eventually (no exact timeline yet, though).

Blog:
https://blog.mozilla.org/addons/2019/03/26/extensions-in-firefox-67/#userscripts
MDN Docs:
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/userScripts
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/contentScripts

@bershanskiy
Copy link
Author

@Hlsgs
Copy link

Hlsgs commented Oct 31, 2019

Any input on this from the devs would be awesome and highly appreciated @tophf @gera2ld

@tophf
Copy link
Member

tophf commented Nov 1, 2019

Both of us don't use Firefox.

@bershanskiy
Copy link
Author

@tophf So would you be interested in a PR that moves Firefox to the new API (while doing nothing to Chrome)? As far as I understand, currently you have to write somewhat hacky code that would work on both Chrome and Firefox; if so, this API should permanently solve Firefox compatibility and you would need to worry only about Chrome (which might be easier in the long run).

@tophf
Copy link
Member

tophf commented Nov 1, 2019

I might be interested in reviewing such a PR.

@tophf
Copy link
Member

tophf commented Feb 14, 2020

Huh, this API doesn't support regexps in @include or @exclude.

@bershanskiy

This comment has been minimized.

@tophf
Copy link
Member

tophf commented Feb 15, 2020

Globs are not regexps.
https://wiki.greasespot.net/Include_and_exclude_rules

FWIW, an internal workaround may be used for this case: we could extract those regexps to JS checks like /regexp/.test(location.href) at the start of the code provided to browser.userScripts.register(). Scripts with @include regexps will have to run on all URLs for that check to work, obviously.

@tophf
Copy link
Member

tophf commented Mar 16, 2020

Another deficiency of the API that needs a workaround is the injection order. When it's changed via drag'n'drop in the dashboard, all scripts that follow the earliest of the before and after positions of the script will have to be re-registered.

@tophf
Copy link
Member

tophf commented Mar 29, 2020

Another peculiarity/deficiency of the API is that each userscript runs in its own unique security origin (this is how Firefox implements a full sandbox that's similar to the isolated world of a content script) so the following code fails:

window.open(location.href).onload = console.log;

As you can see it opens a same-origin URL but it fails with a cross-origin security error due to unique origin assigned to the userscript when running via browser.userScripts API.

This code works both in page scripts and content scripts which is the expected outcome so to prevent userscripts from breaking we would have to make this injection mode either optional (e.g. @inject-into sandbox) or enable it only for scripts that have GM.* grants and no GM_* grants or even make it an option in UI without a meta key.

@pintassilgo
Copy link

Another peculiarity/deficiency of the API is that each userscript runs in its own unique security origin (this is how Firefox implements a full sandbox that's similar to the isolated world of a content script) so the following code fails:

window.open(location.href).onload = console.log;

This works in FireMonkey:

unsafeWindow.open(location.href).onload = unsafeWindow.console.log;

@tophf
Copy link
Member

tophf commented Nov 3, 2021

Simple examples may be transformed of course but you can't auto-transform complex structures like prototypes/classes. In each case we have to implement byzantine cascades of exportFunction and cloneInto manually.

@tophf
Copy link
Member

tophf commented Feb 20, 2023

ManifestV3 will have a cross-browser API for userscript injection. It'll be a superset of the old Firefox userscripts API and it'll allow injecting into the main world of the page. We'll use it when it's ready.

@ivysrono
Copy link
Contributor

what does main world of the page mean?

@SecT0uch
Copy link

Manifest V3 has been supported for a while now.

What's the status on this subject ?

@tophf
Copy link
Member

tophf commented Oct 12, 2023

The new API is not yet implemented.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants