From 6b2f9b850b03779ab127b749f97d9700c974e06e Mon Sep 17 00:00:00 2001 From: Devlin Cronin Date: Thu, 7 Mar 2024 17:19:40 -0800 Subject: [PATCH 1/8] Proposal: Multiple user script worlds This adds a new API proposal for supporting multiple user script worlds, allowing user script managers to better isolate individual user scripts when multiple may be injected on a given site. This proposal follows the new API proposal process. --- proposals/multiple_user_script_worlds.md | 285 +++++++++++++++++++++++ 1 file changed, 285 insertions(+) create mode 100644 proposals/multiple_user_script_worlds.md diff --git a/proposals/multiple_user_script_worlds.md b/proposals/multiple_user_script_worlds.md new file mode 100644 index 00000000..88b7e259 --- /dev/null +++ b/proposals/multiple_user_script_worlds.md @@ -0,0 +1,285 @@ +# Proposal: Allow multiple user script worlds + +**Summary** + +Allow developers to configure and use multiple user script worlds in the +`browser.userScripts` API. + +**Document Metadata** + +**Author:** rdcronin + +**Sponsoring Browser:** Google Chrome + +**Contributors:** N/A + +**Created:** 2024-03-07 + +**Related Issues:** TODO + +## Motivation + +### Objective + +User scripts are (usually small) scripts that enable myriad use cases by +injecting scripts into different web pages. A user may have many different +user scripts that execute on the same page; however, these scripts are +conceptually distinct from one another and should generally not interact with +each other. + +Today, user script managers take various steps to isolate user scripts as they +are injected, since all user scripts will run either in the context of the +main world or in a single user script world for the extension. This API would +allow user script managers to instead have multiple user script worlds, each +isolated from one another, to reduce the likelihood of user scripts negatively +affecting one another through collisions. + +#### Use Cases + +The primary use case is user script managers that handle multiple, independent +script injections in a single page. + +### Known Consumers + +We anticipate user script managers such as Tampermonkey, Violentmonkey, and +others to use this new capability. + +## Specification + +### Schema + +This change would modify existing schemas. + +Relevant methods and types: + +``` +export namespace userScripts { + export interface WorldProperties { + /** + * Specifies the world csp. The default is the `` `ISOLATED` `` world csp. + */ + csp?: string; + + /** + * Specifies whether messaging APIs are exposed. The default is `false`. + */ + messaging?: boolean; + } + + /** + * Properties for a registered user script. + */ + export interface RegisteredUserScript { + /** + * If true, it will inject into all frames, even if the frame is not the + * top-most frame in the tab. Each frame is checked independently for URL + * requirements; it will not inject into child frames if the URL + * requirements are not met. Defaults to false, meaning that only the top + * frame is matched. + */ + allFrames?: boolean; + /** + * Specifies wildcard patterns for pages this user script will NOT be + * injected into. + */ + excludeGlobs?: string[]; + /** + * Excludes pages that this user script would otherwise be injected into. + * See Match Patterns for more details on the syntax of these strings. + */ + excludeMatches?: string[]; + /** + * The ID of the user script specified in the API call. This property + * must not start with a '_' as it's reserved as a prefix for generated + * script IDs. + */ + id: string; + /** + * Specifies wildcard patterns for pages this user script will be + * injected into. + */ + includeGlobs?: string[]; + /** + * The list of ScriptSource objects defining sources of scripts to be + * injected into matching pages. + */ + js: ScriptSource[]; + /** + * Specifies which pages this user script will be injected into. See + * Match Patterns for more details on the syntax of these strings. This + * property must be specified for ${ref:register}. + */ + matches?: string[]; + /** + * Specifies when JavaScript files are injected into the web page. The + * preferred and default value is document_idle + */ + runAt?: RunAt; + /** + * The JavaScript execution environment to run the script in. The default + * is `USER_SCRIPT` + */ + world?: ExecutionWorld; + } +} +``` + +We will add a new property, `worldId`, to the `WorldProperties` and +`RegisteredUserScript` types, as below. + +``` +export namespace userScripts { + export interface WorldProperties { + /** ++ * Specifies the ID of the specific user script world to update. ++ * If not provided, updates the properties of the default user script world. ++ */ ++ worldId?: string; + + /** + * Specifies the world csp. The default is the `ISOLATED` world csp. + */ + csp?: string; + + /** + * Specifies whether messaging APIs are exposed. The default is `false`. + */ + messaging?: boolean; + } + + /** + * Properties for a registered user script. + */ + export interface RegisteredUserScript { + /** + * If true, it will inject into all frames, even if the frame is not the + * top-most frame in the tab. Each frame is checked independently for URL + * requirements; it will not inject into child frames if the URL + * requirements are not met. Defaults to false, meaning that only the top + * frame is matched. + */ + allFrames?: boolean; + /** + * Specifies wildcard patterns for pages this user script will NOT be + * injected into. + */ + excludeGlobs?: string[]; + /** + * Excludes pages that this user script would otherwise be injected into. + * See Match Patterns for more details on the syntax of these strings. + */ + excludeMatches?: string[]; + /** + * The ID of the user script specified in the API call. This property + * must not start with a '_' as it's reserved as a prefix for generated + * script IDs. + */ + id: string; + /** + * Specifies wildcard patterns for pages this user script will be + * injected into. + */ + includeGlobs?: string[]; + /** + * The list of ScriptSource objects defining sources of scripts to be + * injected into matching pages. + */ + js: ScriptSource[]; + /** + * Specifies which pages this user script will be injected into. See + * Match Patterns for more details on the syntax of these strings. This + * property must be specified for ${ref:register}. + */ + matches?: string[]; + /** + * Specifies when JavaScript files are injected into the web page. The + * preferred and default value is document_idle + */ + runAt?: RunAt; + /** + * The JavaScript execution environment to run the script in. The default + * is `USER_SCRIPT` + */ + world?: ExecutionWorld; + ++ /** ++ * If specified, specifies a specific user script world ID to execute in. ++ * Only valid if `world` is omitted or is `USER_SCRIPT`. If omitted, the ++ * script will execute in the default user script world. ++ */ ++ worldId?: string; + } +} +``` + +Note that the signatures of the related functions, including `configureWorld()`, +`register()`, and others are left unchanged. + +When the developer specifies a `worldId` in either the `WorldProperties` or +a `RegisteredUserScript`, the browser will create a separate user script world +for those cases. If `worldId` is omitted, a "default" user script world will +be used. + +### New Permissions + +No new permissions are necessary. This is inline with the `userScripts` API's +current functionality and purpose. + +### Manifest File Changes + +No manifest file changes are necessary. + +## Security and Privacy + +### Exposed Sensitive Data + +This does not expose any additional sensitive data. + +### Abuse Mitigations + +This API does not provide any additional avenue for abuse beyond what the +`userScripts` API is already capable of. + +Extension developers may abuse this API by requiring too many user script +worlds, which would have a heavy performance cost. However, this is not a +security consideration. Additionally, browsers can mitigate this by enforcing +a limit of the maximum number of user script worlds an extension may register +or have active at a given time. + +These enforcements will be left up to the browser to implement, if they feel +necessary. + +### Additional Security Considerations + +No additional security considerations. This API may (mildly) increase security +by (somewhat) isolating individual user scripts from interacting with one +another. + +## Alternatives + +### Existing Workarounds + +Today, user script managers go to various lengths to try to isolate behavior +between user scripts. This includes having various frozen types, making heavy +use of function closures, ensuring injection before untrusted code, and more. + +These workarounds are fragile and require significantly more complex code in +user script managers, while providing a lesser guarantee of isolation than a +separate user script world would provide. + +### Open Web API + +The concept of user scripts should not be exposed to the web; this should not +be an open web API. + +## Implementation Notes + +N/A + +## Future Work + +With the addition of a `userScripts.execute()` function (as described in +this [PR](https://github.com/w3c/webextensions/pull/540) and +[issue](https://github.com/w3c/webextensions/issues/477), we should also +allow developers to specify the `worldId` when injecting dynamically. This +will behave similarly to its behavior for a `RegisteredUserScript`. From ad67d8c14ef5096007051422420e7bbb917e6b1b Mon Sep 17 00:00:00 2001 From: Devlin Cronin Date: Wed, 13 Mar 2024 15:14:15 -0700 Subject: [PATCH 2/8] Address Rob's and Timothy's feedback --- proposals/multiple_user_script_worlds.md | 43 ++++++++++++++++++++---- 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/proposals/multiple_user_script_worlds.md b/proposals/multiple_user_script_worlds.md index 88b7e259..2bb60c77 100644 --- a/proposals/multiple_user_script_worlds.md +++ b/proposals/multiple_user_script_worlds.md @@ -15,7 +15,7 @@ Allow developers to configure and use multiple user script worlds in the **Created:** 2024-03-07 -**Related Issues:** TODO +**Related Issues:** [565](https://github.com/w3c/webextensions/issues/565) ## Motivation @@ -78,43 +78,51 @@ export namespace userScripts { * frame is matched. */ allFrames?: boolean; + /** * Specifies wildcard patterns for pages this user script will NOT be * injected into. */ excludeGlobs?: string[]; + /** * Excludes pages that this user script would otherwise be injected into. * See Match Patterns for more details on the syntax of these strings. */ excludeMatches?: string[]; + /** * The ID of the user script specified in the API call. This property * must not start with a '_' as it's reserved as a prefix for generated * script IDs. */ id: string; + /** * Specifies wildcard patterns for pages this user script will be * injected into. */ includeGlobs?: string[]; + /** * The list of ScriptSource objects defining sources of scripts to be * injected into matching pages. */ js: ScriptSource[]; + /** * Specifies which pages this user script will be injected into. See * Match Patterns for more details on the syntax of these strings. This * property must be specified for ${ref:register}. */ matches?: string[]; + /** * Specifies when JavaScript files are injected into the web page. The * preferred and default value is document_idle */ runAt?: RunAt; + /** * The JavaScript execution environment to run the script in. The default * is `USER_SCRIPT` @@ -125,7 +133,8 @@ export namespace userScripts { ``` We will add a new property, `worldId`, to the `WorldProperties` and -`RegisteredUserScript` types, as below. +`RegisteredUserScript` types, as below. Changed fields are indicated with +"+". ``` export namespace userScripts { @@ -133,11 +142,12 @@ export namespace userScripts { /** + * Specifies the ID of the specific user script world to update. + * If not provided, updates the properties of the default user script world. ++ * Values with leading underscores (`_`) are reserved. + */ + worldId?: string; /** - * Specifies the world csp. The default is the `ISOLATED` world csp. + * Specifies the world's CSP. The default is the `ISOLATED` world CSP. */ csp?: string; @@ -159,43 +169,51 @@ export namespace userScripts { * frame is matched. */ allFrames?: boolean; + /** * Specifies wildcard patterns for pages this user script will NOT be * injected into. */ excludeGlobs?: string[]; + /** * Excludes pages that this user script would otherwise be injected into. * See Match Patterns for more details on the syntax of these strings. */ excludeMatches?: string[]; + /** * The ID of the user script specified in the API call. This property * must not start with a '_' as it's reserved as a prefix for generated * script IDs. */ id: string; + /** * Specifies wildcard patterns for pages this user script will be * injected into. */ includeGlobs?: string[]; + /** * The list of ScriptSource objects defining sources of scripts to be * injected into matching pages. */ js: ScriptSource[]; + /** * Specifies which pages this user script will be injected into. See * Match Patterns for more details on the syntax of these strings. This * property must be specified for ${ref:register}. */ matches?: string[]; + /** * Specifies when JavaScript files are injected into the web page. The * preferred and default value is document_idle */ runAt?: RunAt; + /** * The JavaScript execution environment to run the script in. The default * is `USER_SCRIPT` @@ -206,6 +224,7 @@ export namespace userScripts { + * If specified, specifies a specific user script world ID to execute in. + * Only valid if `world` is omitted or is `USER_SCRIPT`. If omitted, the + * script will execute in the default user script world. ++ * Values with leading underscores (`_`) are reserved. + */ + worldId?: string; } @@ -217,9 +236,18 @@ Note that the signatures of the related functions, including `configureWorld()`, When the developer specifies a `worldId` in either the `WorldProperties` or a `RegisteredUserScript`, the browser will create a separate user script world -for those cases. If `worldId` is omitted, a "default" user script world will +for those cases. If `worldId` is omitted, the default user script world will be used. +Additionally, `runtime.Port` and `runtime.MessageSender` will each be extended +with a new, optional `userScriptWorldId` property that will be populated in the +arguments passed to `runtime.onUserScriptConnect` and +`runtime.onUserScriptMessage` if the message initiator is a non-default user +script world. We do not need to populate a value for messages from the default +user script world, since this is unambiguous given the distinction in the +event listeners (`onUserScriptMessage` already indicates the message was from +a user script). + ### New Permissions No new permissions are necessary. This is inline with the `userScripts` API's @@ -279,7 +307,10 @@ N/A ## Future Work With the addition of a `userScripts.execute()` function (as described in -this [PR](https://github.com/w3c/webextensions/pull/540) and -[issue](https://github.com/w3c/webextensions/issues/477), we should also +[PR 540](https://github.com/w3c/webextensions/pull/540) and +[issue 477](https://github.com/w3c/webextensions/issues/477), we should also allow developers to specify the `worldId` when injecting dynamically. This will behave similarly to its behavior for a `RegisteredUserScript`. + +We have also discussed enabling more seamless inter-world communication, and +the `worldId` could potentially be used in those purposes. From f0f6c696a952ddd6084c45cabc7642970224a2b3 Mon Sep 17 00:00:00 2001 From: Devlin Cronin Date: Fri, 29 Mar 2024 11:30:23 -0700 Subject: [PATCH 3/8] Update diff styling --- proposals/multiple_user_script_worlds.md | 192 +++++++++++------------ 1 file changed, 96 insertions(+), 96 deletions(-) diff --git a/proposals/multiple_user_script_worlds.md b/proposals/multiple_user_script_worlds.md index 2bb60c77..96b391ae 100644 --- a/proposals/multiple_user_script_worlds.md +++ b/proposals/multiple_user_script_worlds.md @@ -133,102 +133,102 @@ export namespace userScripts { ``` We will add a new property, `worldId`, to the `WorldProperties` and -`RegisteredUserScript` types, as below. Changed fields are indicated with -"+". - -``` -export namespace userScripts { - export interface WorldProperties { - /** -+ * Specifies the ID of the specific user script world to update. -+ * If not provided, updates the properties of the default user script world. -+ * Values with leading underscores (`_`) are reserved. -+ */ -+ worldId?: string; - - /** - * Specifies the world's CSP. The default is the `ISOLATED` world CSP. - */ - csp?: string; - - /** - * Specifies whether messaging APIs are exposed. The default is `false`. - */ - messaging?: boolean; - } - - /** - * Properties for a registered user script. - */ - export interface RegisteredUserScript { - /** - * If true, it will inject into all frames, even if the frame is not the - * top-most frame in the tab. Each frame is checked independently for URL - * requirements; it will not inject into child frames if the URL - * requirements are not met. Defaults to false, meaning that only the top - * frame is matched. - */ - allFrames?: boolean; - - /** - * Specifies wildcard patterns for pages this user script will NOT be - * injected into. - */ - excludeGlobs?: string[]; - - /** - * Excludes pages that this user script would otherwise be injected into. - * See Match Patterns for more details on the syntax of these strings. - */ - excludeMatches?: string[]; - - /** - * The ID of the user script specified in the API call. This property - * must not start with a '_' as it's reserved as a prefix for generated - * script IDs. - */ - id: string; - - /** - * Specifies wildcard patterns for pages this user script will be - * injected into. - */ - includeGlobs?: string[]; - - /** - * The list of ScriptSource objects defining sources of scripts to be - * injected into matching pages. - */ - js: ScriptSource[]; - - /** - * Specifies which pages this user script will be injected into. See - * Match Patterns for more details on the syntax of these strings. This - * property must be specified for ${ref:register}. - */ - matches?: string[]; - - /** - * Specifies when JavaScript files are injected into the web page. The - * preferred and default value is document_idle - */ - runAt?: RunAt; - - /** - * The JavaScript execution environment to run the script in. The default - * is `USER_SCRIPT` - */ - world?: ExecutionWorld; - -+ /** -+ * If specified, specifies a specific user script world ID to execute in. -+ * Only valid if `world` is omitted or is `USER_SCRIPT`. If omitted, the -+ * script will execute in the default user script world. -+ * Values with leading underscores (`_`) are reserved. -+ */ -+ worldId?: string; - } -} +`RegisteredUserScript` types, as below. + +```diff + export namespace userScripts { + export interface WorldProperties { + /** ++ * Specifies the ID of the specific user script world to update. ++ * If not provided, updates the properties of the default user script ++ * world. ++ * Values with leading underscores (`_`) are reserved. ++ */ ++ worldId?: string; + + /** + * Specifies the world's CSP. The default is the `ISOLATED` world CSP. + */ + csp?: string; + + /** + * Specifies whether messaging APIs are exposed. The default is `false`. + */ + messaging?: boolean; + } + + /** + * Properties for a registered user script. + */ + export interface RegisteredUserScript { + /** + * If true, it will inject into all frames, even if the frame is not the + * top-most frame in the tab. Each frame is checked independently for URL + * requirements; it will not inject into child frames if the URL + * requirements are not met. Defaults to false, meaning that only the top + * frame is matched. + */ + allFrames?: boolean; + + /** + * Specifies wildcard patterns for pages this user script will NOT be + * injected into. + */ + excludeGlobs?: string[]; + + /** + * Excludes pages that this user script would otherwise be injected into. + * See Match Patterns for more details on the syntax of these strings. + */ + excludeMatches?: string[]; + + /** + * The ID of the user script specified in the API call. This property + * must not start with a '_' as it's reserved as a prefix for generated + * script IDs. + */ + id: string; + + /** + * Specifies wildcard patterns for pages this user script will be + * injected into. + */ + includeGlobs?: string[]; + + /** + * The list of ScriptSource objects defining sources of scripts to be + * injected into matching pages. + */ + js: ScriptSource[]; + + /** + * Specifies which pages this user script will be injected into. See + * Match Patterns for more details on the syntax of these strings. This + * property must be specified for ${ref:register}. + */ + matches?: string[]; + + /** + * Specifies when JavaScript files are injected into the web page. The + * preferred and default value is document_idle + */ + runAt?: RunAt; + + /** + * The JavaScript execution environment to run the script in. The default + * is `USER_SCRIPT` + */ + world?: ExecutionWorld; + ++ /** ++ * If specified, specifies a specific user script world ID to execute in. ++ * Only valid if `world` is omitted or is `USER_SCRIPT`. If omitted, the ++ * script will execute in the default user script world. ++ * Values with leading underscores (`_`) are reserved. ++ */ ++ worldId?: string; + } + } ``` Note that the signatures of the related functions, including `configureWorld()`, From 316c3495e1f104dfb1bddcabb3d9ff9bb9035e47 Mon Sep 17 00:00:00 2001 From: Devlin Cronin Date: Fri, 29 Mar 2024 11:32:24 -0700 Subject: [PATCH 4/8] Collapse code sections since diffing makes it clear --- proposals/multiple_user_script_worlds.md | 86 +----------------------- 1 file changed, 2 insertions(+), 84 deletions(-) diff --git a/proposals/multiple_user_script_worlds.md b/proposals/multiple_user_script_worlds.md index 96b391ae..11d4f19a 100644 --- a/proposals/multiple_user_script_worlds.md +++ b/proposals/multiple_user_script_worlds.md @@ -48,93 +48,11 @@ others to use this new capability. ### Schema -This change would modify existing schemas. +This change would modify existing schemas. We will add a new property, +`worldId`, to the `WorldProperties` and `RegisteredUserScript` types, as below. Relevant methods and types: -``` -export namespace userScripts { - export interface WorldProperties { - /** - * Specifies the world csp. The default is the `` `ISOLATED` `` world csp. - */ - csp?: string; - - /** - * Specifies whether messaging APIs are exposed. The default is `false`. - */ - messaging?: boolean; - } - - /** - * Properties for a registered user script. - */ - export interface RegisteredUserScript { - /** - * If true, it will inject into all frames, even if the frame is not the - * top-most frame in the tab. Each frame is checked independently for URL - * requirements; it will not inject into child frames if the URL - * requirements are not met. Defaults to false, meaning that only the top - * frame is matched. - */ - allFrames?: boolean; - - /** - * Specifies wildcard patterns for pages this user script will NOT be - * injected into. - */ - excludeGlobs?: string[]; - - /** - * Excludes pages that this user script would otherwise be injected into. - * See Match Patterns for more details on the syntax of these strings. - */ - excludeMatches?: string[]; - - /** - * The ID of the user script specified in the API call. This property - * must not start with a '_' as it's reserved as a prefix for generated - * script IDs. - */ - id: string; - - /** - * Specifies wildcard patterns for pages this user script will be - * injected into. - */ - includeGlobs?: string[]; - - /** - * The list of ScriptSource objects defining sources of scripts to be - * injected into matching pages. - */ - js: ScriptSource[]; - - /** - * Specifies which pages this user script will be injected into. See - * Match Patterns for more details on the syntax of these strings. This - * property must be specified for ${ref:register}. - */ - matches?: string[]; - - /** - * Specifies when JavaScript files are injected into the web page. The - * preferred and default value is document_idle - */ - runAt?: RunAt; - - /** - * The JavaScript execution environment to run the script in. The default - * is `USER_SCRIPT` - */ - world?: ExecutionWorld; - } -} -``` - -We will add a new property, `worldId`, to the `WorldProperties` and -`RegisteredUserScript` types, as below. - ```diff export namespace userScripts { export interface WorldProperties { From 0ce3b976bb25c8be69c81878e07a171d39e8f172 Mon Sep 17 00:00:00 2001 From: Devlin Cronin Date: Mon, 1 Apr 2024 14:45:19 -0700 Subject: [PATCH 5/8] Expand API for better world management Expand the proposal to include: - Two new functions, `removeWorld()` and `getWorldConfigurations()`. - Notes about how the worlds behave when injecting. - Notes on world persistence and world limits. --- proposals/multiple_user_script_worlds.md | 52 ++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/proposals/multiple_user_script_worlds.md b/proposals/multiple_user_script_worlds.md index 11d4f19a..8000e246 100644 --- a/proposals/multiple_user_script_worlds.md +++ b/proposals/multiple_user_script_worlds.md @@ -146,16 +146,37 @@ Relevant methods and types: + */ + worldId?: string; } + + ... + ++ /** ++ * Removes the configuration for a given world. ++ */ ++ export function removeWorld(worldId: string): Promise; ++ ++ /** ++ * Returns a promise that resolves to an array of the the configurations ++ * for all user script worlds. ++ */ ++ export function getWorldConfigurations(): Promise; } ``` Note that the signatures of the related functions, including `configureWorld()`, `register()`, and others are left unchanged. -When the developer specifies a `worldId` in either the `WorldProperties` or -a `RegisteredUserScript`, the browser will create a separate user script world -for those cases. If `worldId` is omitted, the default user script world will -be used. +When the developer specifies a `RegisteredUserScript`, the browser will use a +separate user script world when injecting the scripts into a document. If +`worldId` is omitted, the default user script world will be used. + +Worlds may be configured via `userScripts.configureWorld()` by indicating the +given `worldId`. User scripts injected into a world with the given `worldId` +will have the associated properties from the world configuration. If a world +does not have a corresponding configuration, it uses the default user script +world properties. + +World configurations can be removed via the new `userScripts.removeWorld()` +method. Additionally, `runtime.Port` and `runtime.MessageSender` will each be extended with a new, optional `userScriptWorldId` property that will be populated in the @@ -166,6 +187,29 @@ user script world, since this is unambiguous given the distinction in the event listeners (`onUserScriptMessage` already indicates the message was from a user script). +### Behavioral Notes + +#### World Persistence + +Configured worlds are persisted until the owning extension is updated (in order +to align with the behavior of the rest of the `userScripts` API) or manually +removes them via the new `userScripts.removeWorld()` method. + +#### World Limits + +User agents may place limits on both the number of registered worlds and the +number of worlds that may be active in a given document. These limits may be +different (since an extension may want more individual world configurations than +they would expect to be practically encountered on a given site). + +If an extension reaches the limit of the number of registered worlds, attempts +to register a new world via `userScripts.configureWorld()` will fail with an +error. + +If an extension tries to inject more scripts into a single document than the +per-document limit, all additional scripts will be injected into the default +world. + ### New Permissions No new permissions are necessary. This is inline with the `userScripts` API's From c50d727a5838f18691640bd086ebbfdbc84f63cd Mon Sep 17 00:00:00 2001 From: Devlin Cronin Date: Wed, 3 Apr 2024 15:04:09 -0700 Subject: [PATCH 6/8] Address Rob's latest comments --- proposals/multiple_user_script_worlds.md | 28 +++++++++++++++--------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/proposals/multiple_user_script_worlds.md b/proposals/multiple_user_script_worlds.md index 8000e246..c4c6e189 100644 --- a/proposals/multiple_user_script_worlds.md +++ b/proposals/multiple_user_script_worlds.md @@ -56,7 +56,7 @@ Relevant methods and types: ```diff export namespace userScripts { export interface WorldProperties { - /** ++ /** + * Specifies the ID of the specific user script world to update. + * If not provided, updates the properties of the default user script + * world. @@ -150,9 +150,12 @@ Relevant methods and types: ... + /** -+ * Removes the configuration for a given world. ++ * Resets the configuration for a given world. Any scripts that inject into ++ * the world with the specified ID will use the default world configuration. ++ * Does nothing (but does not throw an error) if provided a `worldId` that ++ * does not correspond to a current configuration. + */ -+ export function removeWorld(worldId: string): Promise; ++ export function resetWorldConfiguration(worldId: string): Promise; + + /** + * Returns a promise that resolves to an array of the the configurations @@ -173,10 +176,15 @@ Worlds may be configured via `userScripts.configureWorld()` by indicating the given `worldId`. User scripts injected into a world with the given `worldId` will have the associated properties from the world configuration. If a world does not have a corresponding configuration, it uses the default user script -world properties. +world properties. Any existing worlds are not directly affected by +`userScripts.configureWorld()` calls; however, the browser may revoke +certain privileges (for instance, message calls from existing user script worlds +may beging to fail if the extension sets `messaging` to false). This is inline +with behavior extensions encounter when e.g. the extension is unloaded and the +content script continues running. -World configurations can be removed via the new `userScripts.removeWorld()` -method. +World configurations can be removed via the new +`userScripts.resetWorldConfiguration()` method. Additionally, `runtime.Port` and `runtime.MessageSender` will each be extended with a new, optional `userScriptWorldId` property that will be populated in the @@ -193,7 +201,7 @@ a user script). Configured worlds are persisted until the owning extension is updated (in order to align with the behavior of the rest of the `userScripts` API) or manually -removes them via the new `userScripts.removeWorld()` method. +removes them via the new `userScripts.resetWorldConfiguration()` method. #### World Limits @@ -202,9 +210,9 @@ number of worlds that may be active in a given document. These limits may be different (since an extension may want more individual world configurations than they would expect to be practically encountered on a given site). -If an extension reaches the limit of the number of registered worlds, attempts -to register a new world via `userScripts.configureWorld()` will fail with an -error. +If an extension reaches the limit of the number of registered world +configurations, attempts to register a new world via +`userScripts.configureWorld()` will fail with an error. If an extension tries to inject more scripts into a single document than the per-document limit, all additional scripts will be injected into the default From d087168221bc78d7747def3e68ebedecdb574748 Mon Sep 17 00:00:00 2001 From: Devlin Cronin Date: Thu, 4 Apr 2024 16:37:01 -0700 Subject: [PATCH 7/8] Address more review comments --- proposals/multiple_user_script_worlds.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/proposals/multiple_user_script_worlds.md b/proposals/multiple_user_script_worlds.md index c4c6e189..2a99bb3a 100644 --- a/proposals/multiple_user_script_worlds.md +++ b/proposals/multiple_user_script_worlds.md @@ -179,7 +179,7 @@ does not have a corresponding configuration, it uses the default user script world properties. Any existing worlds are not directly affected by `userScripts.configureWorld()` calls; however, the browser may revoke certain privileges (for instance, message calls from existing user script worlds -may beging to fail if the extension sets `messaging` to false). This is inline +may beging to fail if the extension sets `messaging` to false). This is in line with behavior extensions encounter when e.g. the extension is unloaded and the content script continues running. @@ -253,13 +253,20 @@ No additional security considerations. This API may (mildly) increase security by (somewhat) isolating individual user scripts from interacting with one another. +Note that since isolated world boundaries are not considered "hard" boundaries, +we would not consider this isolation a security measure from the browser's +security model (just as we don't consider isolated worlds to be a strict +security boundary today). + ## Alternatives ### Existing Workarounds Today, user script managers go to various lengths to try to isolate behavior -between user scripts. This includes having various frozen types, making heavy -use of function closures, ensuring injection before untrusted code, and more. +between user scripts (for more information, see conversation in +[issue 279](https://github.com/w3c/webextensions/issues/279). This includes +having various frozen types, making heavy use of function closures, ensuring +injection before untrusted code, and more. These workarounds are fragile and require significantly more complex code in user script managers, while providing a lesser guarantee of isolation than a From 85e12350a467c46ded744f2ddbc5cfb926c295af Mon Sep 17 00:00:00 2001 From: Devlin Cronin Date: Fri, 26 Apr 2024 11:29:39 -0700 Subject: [PATCH 8/8] Fix trailing parenthesis --- proposals/multiple_user_script_worlds.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/multiple_user_script_worlds.md b/proposals/multiple_user_script_worlds.md index 2a99bb3a..55d694e1 100644 --- a/proposals/multiple_user_script_worlds.md +++ b/proposals/multiple_user_script_worlds.md @@ -264,7 +264,7 @@ security boundary today). Today, user script managers go to various lengths to try to isolate behavior between user scripts (for more information, see conversation in -[issue 279](https://github.com/w3c/webextensions/issues/279). This includes +[issue 279](https://github.com/w3c/webextensions/issues/279)). This includes having various frozen types, making heavy use of function closures, ensuring injection before untrusted code, and more.