w3c / webappsec-permissions-policy

A mechanism to selectively enable and disable browser features and APIs
https://w3c.github.io/webappsec-permissions-policy/
Other
399 stars 155 forks source link

Set declared policy for powerful features to self by default #532

Open shhnjk opened 1 year ago

shhnjk commented 1 year ago

See this slide for why current structure of Permissions Policy is bad for sites protected by Strict CSP.

For powerful features, we should have self by default in the declared policy in the absence of the Permissions Policy header.

annevk commented 1 year ago

"this slide" doesn't link to a particular slide for me.

Assuming I'm understanding what you are saying correctly, it seems unlikely that at this point we can require everyone to set a Permissions-Policy header in order to be able to delegate permissions to a cross-origin document.

If you let attackers insert an arbitrary iframe element you might have some other issues as well, e.g., with postMessage().

mikewest commented 1 year ago

Talking with @clelland after the discussion at TPAC (minutes), I think there's potentially value in letting developers opt-into a stricter mode of permission policy in which they'd need to declare each of the policy-controlled features they'd like to delegate, whether through a header. or meta tag in <head> or a manifest, or some other means. But I agree with @annevk that it seems unlikely to be doable by default in the short term (and I also agree that permission delegation is not the only risk of embedding unexpected content).

@shhnjk: You mentioned an incremental plan. Do you have a feel for the features you'd like to start with? Where is the risk highest?

shhnjk commented 1 year ago

I think there are 2 initial targets which likely have less cross-origin usages.

  1. New-ish APIs (e.g. display-capture and identity-credentials-get).
  2. High privileged features (e.g. hid and usb).

For permissions which are used broadly (e.g. camera, microphone, and geolocation), it will be tough. But with report-only mode on the way, major sites (such as Google) will have a more practical way to deploy Permissions Policy, and therefore we hope that the number of sites which doesn't set Permissions Policy to decrease over time for such permissions.

Worst case, we can tie the requirement to SecureContext=Injection.

mikewest commented 1 year ago

I think there are 2 initial targets which likely have less cross-origin usages.

Collecting usage data on these would be helpful. That said, USBDevice.open() looks like it's hovering around 0.003% (with a pretty rapid increase in the last month or three: @reillyeon might know what's happening there?). HID seems much more approachable at ~0.0002%.

Worst case, we can tie the requirement to SecureContext=Injection.

As a small note on priorities though, which I think we'll need to think about as we spend whatever deprecation budget we have: I'd much rather prioritize ensuring that folks even begin to have the problem you're pointing to by pushing for requirements around injection mitigation. In the short term, it might be reasonable to prioritize some kind of opt-in inversion for properties who care about this risk (but don't care enough to guard frame creation).

shhnjk commented 1 year ago

Collecting usage data on these would be helpful. That said, USBDevice.open() looks like it's hovering around 0.003% (with a pretty rapid increase in the last month or three: @reillyeon might know what's happening there?). HID seems much more approachable at ~0.0002%.

I don't think all of those counts will break, as we will only break cases where cross-origin iframes have requested access to those permissions. But we should collect data on cross-origin usage to be sure.

As a small note on priorities though, which I think we'll need to think about as we spend whatever deprecation budget we have: I'd much rather prioritize ensuring that folks even begin to have the problem you're pointing to by pushing for requirements around injection mitigation. In the short term, it might be reasonable to prioritize some kind of opt-in inversion for properties who care about this risk (but don't care enough to guard frame creation).

Right, but the dilemma is that the more we start late, the more it gets difficult to change the default. At least if we can add default self to new (and new-ish) APIs, we will have more hope in the future for the rest.

mikewest commented 1 year ago

Collecting usage data on these would be helpful. That said, USBDevice.open() looks like it's hovering around 0.003% (with a pretty rapid increase in the last month or three: @reillyeon might know what's happening there?). HID seems much more approachable at ~0.0002%.

I don't think all of those counts will break, as we will only break cases where cross-origin iframes have requested access to those permissions. But we should collect data on cross-origin usage to be sure.

Makes sense, collecting data does seem to be a good next step!

Right, but the dilemma is that the more we start late, the more it gets difficult to change the default. At least if we can add default self to new (and new-ish) APIs, we will have more hope in the future for the rest.

Sure. I think it's reasonable to aim for that shift for new APIs. I also think it's reasonable to shift existing APIs in that direction. I'm only saying that getting to a point where this layer matters is more important to me, and if we have a limited amount of time to spend on problems, I'd prefer to spend it there.

(We should also collect data on the set of features called on pages with reasonable/better-than-reasonable CSP, of course. That number might be higher than I expect!)

clelland commented 1 year ago

If the goal here is protecting sites which are willing and able to opt into strict CSP, and deploy a PP header in order to delegate anything (which I believe means that they are capable of setting headers in a general case), I think that we should consider a header-based opt-in, rather than changing the defaults for PP across the board.

Would a solution that involved a "set the defaults" directive in the Permissions-Policy header, something akin to *=self in a header like

Permissions-Policy: *=self, some-powerful-feature=(self https://other.site)

potentially work for this scenario?

shhnjk commented 1 year ago

If the goal here is protecting sites which are willing and able to opt into strict CSP, and deploy a PP header in order to delegate anything (which I believe means that they are capable of setting headers in a general case), I think that we should consider a header-based opt-in, rather than changing the defaults for PP across the board.

Would a solution that involved a "set the defaults" directive in the Permissions-Policy header, something akin to *=self in a header like

Permissions-Policy: *=self, some-powerful-feature=(self https://other.site)

potentially work for this scenario?

Yes that works, but I think I want to push for safe defaults if possible. Maybe, the best way is actually to tie self by default to SecureContext=Injection since we want to require Strict CSP, and we already know Strict CSP can't prevent Permission Delegation attack.

WDYT?

reillyeon commented 1 year ago

Features like WebUSB and WebHID already declare a default allowlist of 'self':

This has been my recommendation for all new feature authors.