w3c / webextensions

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

Proposal for Manifest v3: Have less restrictive security measures for force-installed extensions #43

Open nir-walkme opened 3 years ago

nir-walkme commented 3 years ago

Manifest v3 introduces some security improvements which are great for consumers. They reduce the risk that an extension installed from the store will harm the user. This is great as most users lack the knowledge and tools to assess the security level of an extension they install from the store.

On the contrary, in an enterprise use case, the Manifest v3 changes limit the functionality of existing extensions. There are many use cases where an extension requires elevated permissions. For example, extensions used for QA, security or digital adoption. In the enterprise world, extensions are pushed to the end users using an IT policy (either from the store or from a self-hosted location) and the extensions usually go through a security review before being pushed.

Therefore we suggest treating extensions installed manually from the store differently than extensions force-installed. This is already the case for the blocking version of the webRequest API (https://developer.chrome.com/docs/extensions/mv3/intro/mv3-migration/#when-use-blocking-webrequest) so it appears that our line of thought is in the right direction.

As a general rule, we suggest that any security related restriction in the extension would be excluded from force-installed extensions, or at least there would be a discussion about it.

More specifically, our ask is to allow us to load remotely hosted code into a website's page when using force-installed extensions. We believe this has much use in enterprise use cases.

Rob--W commented 3 years ago

@nir-walkme This topic was discussed during the last meeting (https://github.com/w3c/webextensions/blob/main/_minutes/2021-08-05-wecg.md), but we ran out of time. Did you get a satisfactory answer or is there anything else that you'd like to ask/discuss?

nir-walkme commented 3 years ago

@Rob--W Thank you for the discussion yesterday. I feel we made progress but did not finalize this issue.

To re-clarify my request following yesterday's discussion: Every browser has its own way to deploy an extension using IT administrator policy ("Enterprise use case"). The actual deployment method is out of scope of my request. Every browser "knows" if the extension was installed manually from an extension store (For example: addons.mozilla.org or "chrome web store") or if it was installed via IT policy.


So I propose:

  1. Add the following API: GetExtensionInstallMethod() - Returns "Store" / "Enterprise" This would assist with the next proposal

  2. Deprecations in Manifest v3 (or any future version) that were done for security/performance reasons would not be deprecated if the extension was installed by IT administrator policy. The rationale:

Of course, sometimes deprecations are needed in order to move forward to more modern technology, so it is OK to deprecate as long as there is an alternative approach with equivalent functionality.

  1. More specifically, my ask is that executing remotely hosted code would still be allowed for extensions installed by IT administrator policy. I believe this has the largest impact on extension developers and customers.

@Rob--W How do you recommend to move forward with this discussion?

wingman-jr-addon commented 3 years ago

Note from a citizen of the net: as a developer, I would rather go forward with more of a "feature detection" type of API rather than a split based on "Store" vs. "Enterprise". I think if I tried to make my enterprise addon work across different browsers, the different browser vendors may very well have differences in which API's they would view as privileged or not, so I'd end up having to do feature detection anyways. Checking for "Store" vs. "Enterprise" seems like it may end up running into the same problems that JS ran into in the past with checking "IE" vs. "Chrome" vs. "Firefox" that eventually moved towards feature detection. And as a bonus: I don't even have to learn any new API's for checking depending on how it's implemented.

How did you envision that checking would work with GetExtensionInstallMethod()? Perhaps I have not fully grasped your approach.

nir-walkme commented 3 years ago

Hi @wingman-jr-addon . I may actually agree with you that feature detection is better than GetExtensionInstallMethod().

But that is actually not the focus of my request. The important part of my request are points #2 and #3 above. Any thoughts on that?

wingman-jr-addon commented 3 years ago

Well, I think there's a bit of an issue here in point 2 that is rooted precisely in the thinking around point 1. In the meeting notes above, it was brought up that deployment mechanism was out-of-scope. And above in your clarification you call out The actual deployment method is out of scope of my request. However, I believe what you're suggesting here is essentially that the deployment mechanism (force install) dictates the security measures, which rather implies some coupling of the in-scope to the out-of-scope.

Why is this coupling to deployment problematic? As [tomislav] pointed out in the meeting notes, there are already differences in the stance that Chrome and Firefox take. To keep that diversity, I think this proposal could at most say "when force-installed, API x is guaranteed to exist", rather than indicating the inverse that "when not force-installed, API x is guaranteed not to exist".

But that still ties the wording to the deployment method. I think from a specification perspective it might be better to indicate "trusted context" or something like that, as there might be additional ways of achieving that. For example, Mozilla has been trying out a "Recommended Extensions" approach where some number of addons go through a security review before becoming "recommended". Now, I'm not sure that I particularly like the idea of introducing two levels of privilege here at any level, but at least I think something like "trusted context" might better embrace a variety of approaches to ensuring security and perhaps be a better abstraction for a specification - if this type of approach were taken.

I do not have thoughts on point 3, but I believe that it should be split off into its own issue. Saying point 3 is the heart of the issue when it is not part of the main title seems problematic. A general security mechanism and a specific API are two quite different things.

nir-walkme commented 3 years ago

Thanks @wingman-jr-addon

I agree with your points.

It does make more sense for the specification to be more abstract, so we can define an extension running in "normal mode" and "trusted mode".

"normal mode" would be the default mode for extensions installed from the store. Each browser would define when to treat the extension as "trusted mode". Examples for "trusted mode" use cases:

  1. Extensions force-installed.
  2. Extensions from the store that have gone through a more rigorous review.
  3. A browser power-user may enable it in the browser's settings.
  4. When working in developer mode.
  5. When loading unpacked extension.
  6. Extensions may declare themselves as requiring "trusted mode" and so installation from the store would provide a proper alert on this to the user.

The specification will mention that on "trusted mode", API/capability X is guaranteed to exist. Browser may decide if to include API/capability X also in "normal mode".

I realize that introducing these modes is adding more complexity, but I would like to reiterate the need here: Manifest V3 has introduced several deprecations. Those deprecations means that functionality that have worked for years may stop working, causing major impact to both developers and customers. I believe that "Trusted mode" is a good balance between protecting the "general population" while not hurting the professional users. Those "professional users" are not necessarily power-users or developers, but can be 100s of millions of users that are using the browser in an enterprise environment.

More specifically, I suggest that the following capabilities would work in "trusted mode" (it is up to the browsers to decide if they should work in "normal mode" as well):

Rob--W commented 3 years ago

The implementation details aside, what I see in this request looks like this:

  1. Chrome limits Manifest V3 extensions' use of blocking webRequest and remote code execution.
  2. Chrome offers the ability for enterprise admins to relax the restrictions for blocking webRequest.
  3. You are maintaining an extension that is force-installed in an enterprise setting.
  4. You are looking for a way for your extension to still be functional under Manifest v3.
  5. Conclusion: request to allow enterprise-installed/trusted extensions to use APIs that have been deprecated.

I can follow the train of thoughts, but don't view the conclusion as an actionable point in this community group. Enterprise policies are currently not standardized and the set of supported policies is browser-specific. This is not likely to change. "Deployment mechanisms" are explicitly outside the scope of this group according to the charter document.

If you believe that an API is too limited, file new issues requesting for specific functionality with specific use cases. In that way, all extension developers can benefit from improvements, and not just the group of enterprise extension developers.

So I propose:

  1. Add the following API: GetExtensionInstallMethod() - Returns "Store" / "Enterprise"

This already exists in the form of the installType property in the management API https://developer.chrome.com/docs/extensions/reference/management/#type-ExtensionInstallType https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/management/ExtensionInfo

I question the value of this information for an extension though. Feature detection is generally more effective than checking whether an extension fits in a specific bucket.

  1. More specifically, my ask is that executing remotely hosted code would still be allowed for extensions installed by IT administrator policy. I believe this has the largest impact on extension developers and customers.

Manifest v2 (note: the existing v2, not v3) extensions are already not allowed to execute remote code with very privileged extension APIs (e.g. blocked by the default CSP in extension pages). This restriction is not going to be lifted, so it is very unlikely for a request to (broadly) allow "executing remotely hosted code" to be accepted. If there are specific forms of "remotely hosted code" that you have in mind, please mention that instead.

cuylerstuwe commented 3 years ago

There's a case for SMBs here that seems to be ignored; Many SMBs don't have an IT department, but certainly need custom Chrome extensions written to handle their business operations.

I wrote an extension, for example, whose purpose was to extend web-based POS software for a consignment shop in LA. We had them install this as an unpacked extension in dev mode, so that we could take whatever steps were necessary in order to meet their needs for this internal tools, regardless of what the CWS thought about it.

A large number of these users we extension specialists write internal tools for are not technically-saavy users. They therefore can't be expected to set up and/or maintain any sort of enterprise management.

Perhaps whatever extra capability is granted to extensions force-installed by enterprise policy can also extend to unpacked extensions manually installed by the user. This would not only greatly improve the development of said enterprise extensions, but also improve accessibility to SMBs who don't want/need their extensions available to the public and don't have the IT capacity to maintain enterprise deployment.

Rob--W commented 3 years ago

There's a case for SMBs here that seems to be ignored; Many SMBs don't have an IT department, but certainly need custom Chrome extensions written to handle their business operations.

Perhaps whatever extra capability is granted to extensions force-installed by enterprise policy can also extend to unpacked extensions manually installed by the user. This would not only greatly improve the development of said enterprise extensions, but also improve accessibility to SMBs who don't want/need their extensions available to the public and don't have the IT capacity to maintain enterprise deployment.

I'm actually accounting for SMB that don't use enterprise deployment; in my previous comment I suggested to be specific about use cases so that "all extension developers can benefit from improvements, and not just the group of enterprise extension developers."

I believe that the author of this issue is not specifically asking to restrict features to enterprise, but to allow them to use certain features whose availability are at risk (and suggesting to introduce enterprise-specific functionality in case this constraint would make it more likely to support the functionality).

nir-walkme commented 3 years ago

@cuylerstuwe and @Rob--W I agree that it is better to find solutions that can benefit all extensions developers and not just enterprise use case. My suggestion revolving around force-installed is just as a means to "workaround" new security-related V3 restrictions that make more sense to be removed in an enterprise world.

Let me try to pitch an idea that can benefit all.

This restriction is not going to be lifted, so it is very unlikely for a request to (broadly) allow "executing remotely hosted code" to be accepted. If there are specific forms of "remotely hosted code" that you have in mind, please mention that instead.

How about allowing "remotely hosted code" from pre-defined domains only that are explicitly written in the manifest file in a "match pattern" format? Those remote hosted code domains would be visible to users installing the extension. For example, when installing the extension it will prompt to the user: "The extension can run remote scripts hosted on example.com" and ask the user to approve this.

carlosjeurissen commented 3 years ago

@nir-walkme without saying whether or not this should be supported. Instead of having a separate key with a match pattern in the manifest we can use existing tech like the content_security_policy which is exactly made for that. Namely the script-src, script-src-elem and script-src-attr directives.

nir-walkme commented 3 years ago

@carlosjeurissen When I refer to "executing remotely hosted code" I am referring mostly to "userscripts", meaning remotely hosted scripts that run in the page context (similar to Greasemonkey/Tampermonkey). This includes the ability to execute the script in the page context even if the page is blocking that using content security policy.

I believe the content_security_policy in the manifest files refers only to extension pages and not to the use case I mentioned.

What do you think?

carlosjeurissen commented 3 years ago

@nir-walkme In the case of content scripts, it could be done using the content_security_policy.content_scripts property. This property has been proposed and worked on my Mozilla Firefox. See announcement. When it comes to injecting remote hosted code in the website context itself (not the content script), this is determined by the page CSP. Which could be modified using the chrome.webRequest API or similar.

Everything else would not be a blocker for force-installed extensions as they are policies from stores and not restrictions on a browser level.

The content_security_policy can be discussed here.

nir-walkme commented 3 years ago

In Manifest v2 it was possible to injects remote scripts into the page's context using a content script, including bypassing the page's CSP and without the need to modify the CSP using chrome.webRequest API. I would still like to be able to achieve this in Manifest V3 because using chrome.webRequest API has two problems:

  1. This does not work when the page's CSP is defined using a meta tag (and not HTTP header).
  2. The blocking version of chrome.webRequest API is deprecated in Manifest V3 in Chrome (for non force-installed extensions).

Therefore I suggest to keep the Manifest v2 behavior, at least for pre-defined domains, as suggested before.

xeenon commented 2 years ago

Safari does not currently support force-installed extensions.