w3c / webextensions

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

User scripts in Manifest V3 #279

Open dotproto opened 1 year ago

dotproto commented 1 year ago

PLACEHOLDER: We have a couple of issues related to user scripts support in Manifest V3, but nothing that currently feels like a good tracking issue. This issue intends to fill that gap by consolidating discussion of Manifest V3 API considerations in one place.

erosman commented 1 year ago

The extension-userscript relationship, is similar to the browser-extension relationship.

Extensions have a subset of capabilities of the browsers. Userscripts also have a subset of capabilities of the extensions.

  • Extension only uses content script feature

Extension can inject script into content, page & more. Extension can do whatever a userscript does and more.

  • Extension opens source code to the user

Userscript source code is also available to the users. Furthermore, not all extensions are open source.

  • Extension explicitly tells the user when/how the code run

Ideally, true but not 100% in practice. There are many aspects of the extensions that are not evident due to practicality or other reasons. GA is a prime example in many extensions. How many extensions that use GA advertise its use?

  • After the user has read above information, and the user chooses to install the extension.

The same applies to userscripts. It is extremely rare that a user installs a userscript without having read what it does.

:pushpin: Nonetheless, installing a userscript, good or bad, is users' choice, and users' choice must be respected.

Furthermore, as mentioned earlier, userscripts are not regulated by the browser or extension stores. All browser and extension developers can do is to provide an as-safe-as-possible environment for it. AFA I understand, the purpose of this topic is how best to provide the aforementioned environment.


Footnote

Even with the current restrictions in MV3, it is possible to create an extension that supports userscripts, albeit it would not be as safe as a properly thought of environment.

hanguokai commented 1 year ago

The above comment, I think you understand what I said, and this is what everyone here knows.

xckai commented 1 year ago

Look forward to seeing how it going! A balance should be struck between dev's innovation and user's safety

Rob--W commented 1 year ago

In today's WECG meeting, someone asked for a summary of the user scripts meeting. That meeting had its meeting notes merged in #324, now available at https://github.com/w3c/webextensions/blob/main/_minutes/2022-11-15-wecg-userscripts.md

The summary is as follows:

The original goal of the meeting was to review the goals and scope of the user script API design. Google’s objective of this effort is to reach feature parity with MV2, and identify the foundations needed for future enhancements.

The initial API suggestion shared by Simeon was to add a “code” parameter to the scripting.registerContentScripts API to allow execution of strings. I recommended at least introducing a new userscript “world” for security reasons. But even with this, the work in progress API design would not address the needs of user script managers (background in this comment).

In the design of a user script API, there are roughly two approaches to take: let the browser manage the matching and injection, or let an extension run an all_urls content script that takes care of the injection. User script managers currently do the latter, and when asked, the Tampermonkey dev in the meeting expressed the desire to continue doing this. This reduces the scope of the API design.

The main blocker for user script managers in MV3 compared to MV2 is the inability to run strings as code in the main world (page’s context). In MV2 an inline <script> element offered this capability in Chrome, but MV3 has a CSP in content scripts that blocks this. The work-in-progress API fills the gap, not by the “code” parameter, but due to not enforcing a CSP in the userscript world. Instead of working around the limitation via this accidental implementation detail, I proposed to focus on two API aspects: allowing a content script to run a string as code in the main world, and a mechanism for secure cross-world communication.

tophf commented 1 year ago

allowing a content script to run a string as code in the main world

FWIW, there's even a ticket for Chrome: https://crbug.com/1207006

Getfree commented 1 year ago

In the design of a user script API, there are roughly two approaches to take: let the browser manage the matching and injection, or let an extension run an all_urls content script that takes care of the injection. User script managers currently do the latter, and when asked, the Tampermonkey dev in the meeting expressed the desire to continue doing this. This reduces the scope of the API design.

Am I misinterpreting or does this mean that the new API goal is to please a minute number of developers who happen to be the authors of a specific type of extension?

What about extensions that let the user run scripts at any given moment? That is, not at page load, or page idle, but at any other moment the user desires to do so. For example, will it be possible to create an extension that allows the user to run a given script in a given tab immediately? i.e. not in the future, but right now at this very moment when a page is already loaded in the given tab. Extensions that allow users to automate tasks such as filling form fields or clicking on buttons depend on that functionality.

brunoais commented 1 year ago

Extensions that allow users to automate tasks such as filling form fields or clicking on buttons depend on that functionality.

Can't you do that with only premade code? With the user just mentioning what he wants to do and you run functions you already made? Or do you mean actual custom code?

tophf commented 1 year ago

Am I misinterpreting

Apparently you are. The desire is to retain the control of an extension over how and when the injection/matching takes place.

Getfree commented 1 year ago

Can't you do that with only premade code? With the user just mentioning what he wants to do and you run functions you already made? Or do you mean actual custom code?

Custom code, of course. Snippets of Javascript provided by the user.


The desire is to retain the control of an extension over how and when the injection/matching takes place.

That's exactly what I meant with "specific type of extension". The "matches" parameter determines the URLs where the script must be injected and the "runAt" parameter has only 3 possibilities. Which means this API proposal only attempts to support user script managers such as Grease Monkey and similar. The use case I described in my previous comment won't be possible.

tophf commented 1 year ago

The quote is rather vague. All it says is "continue doing this", so I assume "this" means everything userscript extensions are currently doing and that includes arbitrary execution of code via executeScript which Tampermonkey needs anyway for its @run-at context-menu.

Regardless of these particulars, a "userscript extension" means any extension which is designed to run user-provided code, not just userscript managers. Apparently this is yet another vague term that might need a better substitute.

erosman commented 1 year ago

Initially, MV3 did not allow for injection of code strings. The purpose of this topic is to discuss how user-code can be injected by an extension as safely as possible.

What about extensions that let the user run scripts at any given moment?

For example, will it be possible to create an extension that allows the user to run a given script in a given tab immediately?

Custom code, of course. Snippets of Javascript provided by the user.

Sure....

That's exactly what I meant with "specific type of extension". The "matches" parameter determines the URLs where the script must be injected and the "runAt" parameter has only 3 possibilities.

That is a specific registration of JS/CSS for auto-injection, which is available to any extension and used by many non-userscript-manager extensions.

Getfree commented 1 year ago

@erosman, do you mean that scripting.executeScript() will also support a code parameter? I couldn't find that in the API proposal document.

erosman commented 1 year ago

@erosman, do you mean that scripting.executeScript() will also support a code parameter? I couldn't find that in the API proposal document.

It is also a part of the proposal to support the injection of code parameter or similar in scripting.executeScript().

The important part is to finalise where (which context) the user-code will be injected into.

Semi-privileged content context, which is meant for extension's own code, is not best suited for user-script/user-code.

EmiliaPaz commented 1 year ago

Proposal, that takes into account multiple points discussed here, was moved to PR #331 to facilitate discussion

Robbendebiene commented 1 year ago

Just want to point out, that there are other use cases for injecting user scripts than just by match patterns. For example mouse gesture extensions want to inject them into a certain tab (active tab) at a certain point (at the end of a a gesture).

Example add-ons with code/implementation reference:

Therefore I plead to have a code parameter for the scripting.executeScript() function as well.

rdcronin commented 3 months ago

This is implemented in Chrome. Future expansions will be tracked separately (you can see some of these in @Rob--W 's comment at https://github.com/w3c/webextensions/issues/279#issuecomment-1254094148). We'll leave this issue open until other browsers implement the core API, and then close this out.