w3c / webextensions

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

Add permissions.requestSiteAccess() API proposal #529

Closed EmiliaPaz closed 3 months ago

EmiliaPaz commented 5 months ago

Proposal for a new API method to allow the extension to show site access requests at runtime without any user gesture in a less-obtrusive way than with permissions.request()

fregante commented 5 months ago

At what point would an extension want to use this? As @xeenon pointed out, how do I know which tab to target if I don't know their URL?

Is this API only useful when the user is already interacting with the extension via sidePanel? That's the only scenario I can think of where the user doesn't have activeTab but the extension would probably want access.

Or maybe is this API meant to preserve access to a tab with a temporary activeTab permission?

I worked on a related UI before (webext-permission-toggle) so I wonder how I could use this.

greghuc commented 5 months ago

I want to make a slightly off-topic comment expanding on what @hanguokai said earlier about host permissions not being bound to Tabs. Sorry for being off-topic, but I think it's worth increasing awareness on this, and whether it's worth a fix. @oliverdunk or @dotproto - I'd be happy for this to be spun off into a separate issue, but I can only describe the problem and not the solution.

There's a confusing situation where an extension would ideally have only "activeTab" permissions ('When You Click the Extension' in the Chrome UI), but needs broad host_permissions at install time ('Can Read / Write Data on All Sites')

The problem happens for an extension that runs on the active-tab when the user clicks the extension button. The extension gains host_permissions to the origin in the top frame (the main web page), but not to any other origins used in rendering the page (like the origin of a remote image hosting service). If the content script then tries to fetch and access a resource from one of these other origins (like a remote-hosted image), then it runs into CORS errors. The current solution used is to request broad host_permissions, and fetch and access these resources from a background script, which is unaffected by CORS.

I ran into this issue when writing an extension that fetched and processed images on the current webpage. @dotproto and I had a Chromium Extensions chat about this back in December 2021. I submitted a Chromium feature request back in July 2022 to allow CORS-free access to dom image elements. However, I'm now thinking this issue should be handled at the CORS level when fetching a resource.

Maybe "activeTab" permission could be relaxed slightly to allow extension access to all origins used in rendering a page. Or at least GET read access. In the previous chat, @dotproto said this wasn't done, as "if a user invokes the extension on a page with, say, social media sharing widgets, it's not clear that the user also wants to grant the extension access to all of those social media sites as well". However, if you're balancing this against the current approach of broad host_permissions to resolve this issue, then a relaxed "activeTab" permission doesn't seem so bad.

Sorry for being off-topic @EmiliaPaz - I thought it was worth adding this comment, given we're covering host_permissions

oliverdunk commented 5 months ago

I want to make a slightly off-topic comment expanding on what @hanguokai said earlier about host permissions not being bound to Tabs. Sorry for being off-topic, but I think it's worth increasing awareness on this, and whether it's worth a fix.

Thanks for raising this. I think there is some overlap since this API will also only grant access to the top-level site's origin. The reasoning for this is very similar to everything you mentioned with the behavior of activeTab today. There is a high level of risk, especially with "tracking pixels" and social media embeds, that users may be granting more access than they realise.

There is actually some precedence for granting more than the current origin with activeTab - I believe Firefox granted access to all frames on a page in MV2. They aligned with Chrome and Safari in MV3 to be consistent, though my understanding at least as of a year ago was that they were still interested in supporting the capability.

All of that said - the general opinion last time I discussed this within Chrome (which I am inclined to agree with) is that we should keep looking for a good solution, but automatically granting access to all origins associated with a tab isn't it. It may reduce the use of widely scoped host permissions, but at the cost of making it harder for users to understand what an extension can do. It doesn't feel like it meaningfully improves the situation unfortunately and it would be better to keep thinking about this.

greghuc commented 5 months ago

@oliverdunk many thanks for the considered response.

I do wonder if the CORS issue I described is narrower that it looks, and predominately applies to images. If so, the solution to this might be image-specific (like my chrome.dom.createDomImageBitmap API proposal), rather than a 'grant wider origin access' solution, and so fix 90+% of issues.

My detailed knowledge of CORS has faded, but if I recollect correctly:

In which case, if extensions are primarily focussed on processing a rendered webpage and associated loaded resources, then the issue becomes image-specific.

oliverdunk commented 5 months ago

the solution to this might be image-specific (like my chrome.dom.createDomImageBitmap API proposal), rather than a 'grant wider origin access' solution, and so fix 90+% of issues.

For your use case it definitely sounds like something narrower in scope might work, though I do share the concerns about doing something cross-origin in nature within a content script. Feel free to ping on the issue and we can keep discussing there 😁

EmiliaPaz commented 4 months ago

In the public WECG meeting (see _minutes/2024-02-29-wecg.md), we decided to move forward with url parameter, and each browser could determine which parameters it requires (e.g Chrome requires tabId or documentId and Safari requires url).

The only decision left is whether the parameters tabId, documentId and url are AND or OR: a) All parameters can be provided and are all matched. b) Only one of the parameters can be provided.

We (Chrome) think option a) is better because it maintains the same signature for all browsers. For example:

permissions.addSiteAccessRequest({tabId: 123, url:"example.com"})

would be a valid API call and behave the same in every browser. They key part here is that every parameter can be provided. While we have discussed tabId by itself doesn't add value to Safari, adding it on top doesn't hurt or could even be helpful. Same with url for Chrome. It leaves the decision to the extension to add more matching granularity.

Option b. means the same signature could not be used across browsers and there would need to be some try/catch or parameter handling.

We believe a. is better for the extensions ecosystem. However, if other browsers prefer b. we will also accept that (since it supports the API proposal goal)