Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: define default for all #189

Open
laukstein opened this issue Jul 17, 2018 · 90 comments
Open

Proposal: define default for all #189

laukstein opened this issue Jul 17, 2018 · 90 comments
Labels
feature question Questions and issues around specific policy-controlled features

Comments

@laukstein
Copy link

I propose Feature-Policy adopt Content-Security-Policy concept and be able to define all default, example:

Feature-Policy: default 'none'
Feature-Policy: default 'none'; fullscreen 'self'

where similarity in CSP would be

Content-Security-Policy: default-src 'none'
Content-Security-Policy: default-src 'none'; img-src 'self'

Otherwise we would be stuck to define all features separately, and since the features list will grow more and more, without the global default it likely will harmful web.

@quisido
Copy link

quisido commented Jul 20, 2018

I second this, and came here for the same suggestion. I would prefer my features be blacklisted by default and whitelisted as needed. My Feature-Policy header is ridiculously long when I have to explicitly define all of them as 'none'.

I also fear that as time progresses, browsers and devices will add non-standardized features to their feature lists. It will become nearly impossible to blacklist all non-standardized features.

@nico3333fr
Copy link

Same suggestion for me: it could be useful to define a default to 'none' and then define what we need on the website/app.

@eeeps
Copy link
Contributor

eeeps commented Jul 24, 2018

Just a note to say that this relates to some of the discussion here: #129, where a default for a specific subset of policy controlled features (client hints) was proposed.

@olmari
Copy link

olmari commented Aug 7, 2018

Definately thumbs up for at least possibility of defining default policy, having a (growing) blacklist with no default is insanity.. Even if some feature gets added and then a site with default policy breaks, it is matter of allowing that one policy.. In current form it is impossible to manage every possible new addition by hand.

@ojanvafai
Copy link
Collaborator

We already have some experience with this with iframe sandbox where we are having difficulty adding new directives because they break pages. With FeaturePolicy, it would be a bit different because we can add new directives without having them be part of the default policy, but it's still hard for me to see how we would be able to add new directives over time to the default policy. With iframe sandbox we can at least prioritize it due to the security benefits.

It's difficult for browsers to ship things that break web sites, especially since many sites are unmaintained, so the ease of sites fixing when we break them doesn't really mitigate that concern.

@olmari
Copy link

olmari commented Aug 24, 2018

@ojanvafai (and all whom may be concerned) AFAIK What we (at least me) are wanting to have an way to tell desired default policy/policies. So without any default defined standard could very well be "opt-in", but if header has something like default 'none' then honour that and deny everything if not told otherwise..

This way sites not having this header at all will continue to work as is today, and administrators who want's to just blacklist certain things regardless of new possible directives can do so, but it would also allow most concerned admins to introduce an default policy and then whitelist allowed ones.

@clelland
Copy link
Collaborator

@olmari, the problem I see with that proposal is that it makes it far more difficult for Feature Policy to be used to remove features from the platform -- we've done this with synchronous XHR, and are looking at other APIs, like document.write, as features we'd like developers to be able to disable. A default 'none' policy would break sites that use those features, certainly, but also any other features that are put under policy control in the future, regardless of how prevalent they are.

I'd love for browsers to be able to experiment with making bigger, more fundamental parts of the platform into policy-controlled features. I'd love for JavaScript, or navigation, to be features that could be disabled in certain contexts, for instance -- if you weren't aware of that, and had set a default 'none' header at some point in the past, then your site could be completely broken, with no warning at all.

@olmari
Copy link

olmari commented Aug 27, 2018

@clelland then you don't just use "default none" policy... I don't know much more clearer I can be on my proposion... Having written no policy would be same as current behaviour. having written default none policy would do just that... All admin configurable...

@clelland
Copy link
Collaborator

@olmari, I realize that you mean for there to be no behaviour changes without explicitly setting the default. The problem that I see is that setting such a default on your site is necessarily a huge risk -- your site would be at far more risk of breaking with future browser revisions than has ever been the case in the past.

Although that's probably not the reality of the situation -- in reality, the existence of such an option, especially if it had any significant level of adoption on the web, would mean that browser vendors would be effectively barred from introducing any new features which would break content on all of those sites. Every new feature decision would have to include serious consideration and discussion about the impact to all of the sites which use default 'none', because breaking compatibility with significant portions of the web isn't something to take lightly -- even if they've opted in.

I do think that I understand the original concern, and the problem with having to specify an ever-growing policy of features to disable. If there were a way to distinguish between "powerful features which you want to think twice about using or granting to frames" from "fundamental features of the web platform", and apply a uniform default to those, then there might be a way to make the proposal work. Without that, it either seems very reckless on the part of the developer, or else severely impacts what kind of features can be defined (which I suspect is the more likely outcome).

Alternative strawman proposal: what if there were a way to set the default for all features which have a default allowlist of 'self'? Those features are already disabled by default in cross-origin frames, which means that people have already at least considered the impact of having them disabled widely. The difference would be that you get to disable them all for your top-level document as well, with a single directive.

You could say something like "default 'self'='none'" (bikeshed colour TBD) or the much more permissive "default 'self'=*" without affecting the operation of features like navigation, scripting, images, forms, or such fundamental 'features'.

@valtlai
Copy link

valtlai commented Aug 28, 2018

Maybe we could require to set up some kind of a report (see Reporting API) to be able to use default? The browser would report when it’s going to support the feature policy for a feature in use on the site.

@laukstein
Copy link
Author

@valtlai, probably best to Report things that fails because of restricted Feature-Policy header. Would basically be similar to CSP report-uri. I really hope we wouldn't need additional header for it.
Perhaps report-uri must be supported also in Feature-Policy header.

Since Feature-Policy are growing bigger affecting not only sensors access, but also UI like animations, fullscreen, JavaScript, etc., things gets more complicated and I hope will not break Web before spec is fixed or depreciated. For example Feature-Policy: default 'none' might break "all" while Feature-Policy: default 'safe' might be fine.

Has anybody thought how Feature-Policy would be affected by browser settings, if Feature-Policy would overwrite browser settings or opposite (I mean these might all be browser defaults or some manually customized by user)?

grabilla g12168

@clelland
Copy link
Collaborator

Feature Policy (and CSP, with the report-to directive) are both being integrated with the Reporting API -- see §9. Reporting, which makes use of an independent Report-To header, rather than report-uri.

@laukstein, I think your other question has to to with permissions -- that screenshot appears to be about setting the default permissions for various APIs. Feature Policy and Permissions do interact, as they affect many of the same features.

In general, the Permissions API is about asking the user whether a particular action is okay, while Feature Policy allows the developer to disable features, or to grant them to cross-origin frames. It's a complicated interaction, but essentially both of the APIs have to agree to allow a feature to be used in order to enable it. If either party (user or developer) says no, then the site cannot use the feature.

@AfroThundr3007730
Copy link

AfroThundr3007730 commented Oct 9, 2018

Although that's probably not the reality of the situation -- in reality, the existence of such an option, especially if it had any significant level of adoption on the web, would mean that browser vendors would be effectively barred from introducing any new features which would break content on all of those sites. Every new feature decision would have to include serious consideration and discussion about the impact to all of the sites which use default 'none', because breaking compatibility with significant portions of the web isn't something to take lightly -- even if they've opted in.

I can see this being very useful for endpoints like a REST API (like in #208), which would use precisely zero of those features, and even completely static sites (e.g. readthedocs for said API) would find this useful. Just like with CSP, setting default-src none would break a more dynamic site immediately, but then you start allowing the origins you need (like 'self'), enabling specific features (allowing unsafe-inline), etc. If a new feature gets added later, you go back and enable it if you need it. The same would apply here.

If part of your site suddenly became very broken overnight after a browser update, you know where to start looking (at least, that's my thought flow after having set such a restrictive security policy). For the small number of people who would find it useful to disable everything, they would likely be more aware of what probably caused breakage, should it occur. Even better if the browser console tells them what's breaking the site, like they do with CSP. Reporting would also help with that, whenever that gets added.

I don't see the default 'none' getting used by very many sites, but it should be an option for those who want to use it. The majority of sites would probably stick to the default policy or set default 'self' (if they implement it at all), and would be unaffected.

@sstelfox
Copy link

sstelfox commented Oct 19, 2018

I don't see the default 'none' getting used by very many sites, but it should be an option for those who want to use it. The majority of sites would probably stick to the default policy or set default 'self' (if they implement it at all), and would be unaffected.

I tend to disagree with this, especially on sites as they're developed. Setting the default wouldn't prevent you (the developer) from using any of the APIs, it just means you have to be cognizant that when you add features you are sure to whitelist them. Personally I see this as a huge benefit as a developer to prevent third party scripts and resources from doing things I don't want.

From what I've read so far about this proposal the default doesn't have to be none but could be any of the valid origin specifications. The two most useful IMHO are self and none. The self default would likely cover some of the earlier concerns about feature expansion in browsers as well, even though new features likely couldn't / wouldn't be usable until a developer made changes to the site anyway.

A casual example of this (and a straw man so take it in the spirit it's given), is that of embedding a youtube video. If I have a default policy of either self or none, when embedding I could prevent the youtube iframe from attempting to enable notifications for the user (I know youtube doesn't do this, but they could in the future, as could any other site that embeds content like this).

Those requests to use functionality are outright frustrating for users when they're not expecting them and I'd much prefer to control that interaction.

@yahesh
Copy link

yahesh commented Nov 11, 2018

Please implement a default directive. I'm thinking of implementing Feature-Policies on all of my sites but am not willing to name each feature individually. So this is a setting-a-default-is-possible-and-I-adopt-this-header or setting-a-default-is-NOT-possible-and-I-DON'T-adopt-this-header decision for me.

Maybe something to consider: This header is meant to be a security filter where additional values are supposedly introduced as needed by individual browser vendors. At the same time you allow default values to be "*" (allow all). This means you are implementing a security filter that works as a blocklist and that has to be modified whenever a vendor introduces a new value. Security filters should work as allowlists so that the person defining it knows exactly what is (going to be) allowed. Or to put it more frankly: Having allow-all defaults is a bad decision. To remedy this bad decision people ask for a functionality to fix this broken design, namely allowing us to set a senseful default value.

Edit: More inclusive wording.

@ewanm89
Copy link

ewanm89 commented Jan 8, 2019

Let me be very clear, this is stupid:

add_header Feature-Policy "autoplay 'none'; camera 'none'; document-domain 'none'; encrypted-media 'none'; fullscreen 'none'; geolocation 'none'; microphone 'none'; midi 'none'; payment 'none'; vr 'none'" always;

The site has no <script> tags, it is a single html file, without any media of any kind. A restful API is in much the same situation. This kind of blacklisting policy is totally stupid in any security context. Always blacklist all and whitelist just what one wants. Your specification does not allow that.

Oh, and I don't want to have to sit down and set such a policy again, or edit it cause a new feature is added that I'm not using anyway.

@triblondon
Copy link

I wonder if a good compromise here is to define some 'bundle' policies.

On the polyfill service we had the problem of people needing to create a very long string of required polyfills. The first thing we did (very unwisely) was to add an all alias, which includes all current and future polyfills. This turns out to be a really bad idea (for example when we shipped Intl, people requesting all were getting every single locale pack, some 25MB of JS!).

Then we made a default alias, which was a movable beast that gradually encompassed more and more polyfills, but we started to find we were breaking sites by adding more polyfills into the group, even though we restricted it to the most common features only.

So what we ended up with was immutable bundle aliases, eg default-3.6, default-3.7, so every time the makeup of the 'default' bundle changed, the alias would also change.

While this comparison isn't completely perfect, I think the solution we ended up with works well for feature policy: we could have some bundle names like antipatterns-1, user-consent-1, and if a new policy is added that guards an antipattern, then a new antipatterns policy is also created.

@ExE-Boss
Copy link

ExE-Boss commented Feb 7, 2019

I think plain default 'none' should disallow everything that isn’t pure JavaScript (i.e. no DOM, no window global (globalThis would be used instead), no nothing).

After that, you would enable features using other directives.

That way, nothing would break by enlarging the scope of default as the scope would be maximum from day 1.

@Jamesernator
Copy link

I would propose an alternative of requiring a date to be provided and that whenever a feature is implemented it has an associated date.

For example we might have the following policies with their dates of addition:

foo-bar : 2018/07/27
baz-bar : 2018/01/23
boz-bar : 2020/11/14
// etc

Now if an header like so is given by a site: FeaturePolicy: default 2019/01/01 'none' is given then foo-bar/baz-bar would be included but boz-bar would not.


How dates would be associated with a policy wouldn't really matter, all that would really need to be a requirement is that a browser couldn't add a new policy for a date in the past.

@ojanvafai
Copy link
Collaborator

Please keep discussion focused on productive debate of the issues. I've deleted the most recent comment on this issue as it consisted solely of a personal attack, which violates the W3C code of conduct (https://www.w3.org/Consortium/cepc/). Repeated violations will result in being blocked from commenting on the repository.

@w3c w3c deleted a comment from RetroGameTalk Feb 28, 2019
@sstelfox
Copy link

Reading through some of the more recent responses it seems like there are two independent groups talking about different meanings of how default should behave.

Originally it was about setting the policy for any features not explicitly otherwise listed in the rest of the feature policy. Specifically, "If my feature policy doesn't mention feature X what policy should be applied". This covers new features that haven't been defined when the policy was configured and prevents having to specify none or self on each of the many different features that most sites won't use.

The second camp that has recently started up, seems to be more discussion what the default setting for each feature should be and have it defined by the w3c policy rather than a developer set default. This is along the lines of "use the default feature settings as defined by the w3c as of 2019-02-28". As other have mentioned, this would be a thorny and contentious road. There is likely no good default set that won't hurt sites out there.

There likely shouldn't be defaults when the header isn't present as has been done with every other security control based on HTTP headers, and when the header is present it only makes sense to allow the developer to set the default policy for everything, then override specifics.

Back to the original feature, the only argument against being able to set a default policy (please correct me if I've missed something) seems to be that a future feature addition might break existing sites that haven't changed. I don't think this will ever be an issue as long as an existing feature is never broken up into more granular features.

For example if Clipboard got broken up into Clipboard-Write and Clipboard-Read, and Clipboard was deprecated the default setting might break existing web apps that rely on doing one of those functions. Preventing this kind of split can be done at the w3c policy level and as long as the developers of the policy are cognizant of this risk there shouldn't be any issue.

In any other case, the only time a default setting would break any functionality is when new functionality is being added to the web app that requires a change to the feature policy. In this scenario the web app is actively being changed and the developer will already have to deploy a new version of the code (it's also worth noting that this would be adding new features to the site, not just a minor bug fix release).

In this case part of the release of the new version would require the header being updated as well to allow for the new feature. This is the same level of effort as other security mitigations such as CSP headers and I think is completely reasonable.

@pabrai pabrai added the feature question Questions and issues around specific policy-controlled features label May 8, 2019
@Jamesernator
Copy link

Jamesernator commented Jun 4, 2019

This is along the lines of "use the default feature settings as defined by the w3c as of 2019-02-28". As other have mentioned, this would be a thorny and contentious road. There is likely no good default set that won't hurt sites out there.

Actually my proposed idea doesn't depend on the W3C managing the dates just that a browser never adds a new policy for a date in the past, each browser could manage their own list simply based on commit date or similar.

The date would be a "I have checked my site works at this date" hence if a new policy is added it should not affect any page which gives a date before the date of the new policy, this doesn't require browsers to agree or even have any rules around it other than "a date for a new policy must not be in the past". This is why I think the date strategy is feasible and very non-thorny and shouldn't even be contentious.

@kifd
Copy link

kifd commented Nov 28, 2023

Yet another +1 to wanting a default policy setting, just like CSP. How is it considered best practice to individually blacklist an ever growing feature set, rather than whitelist the features you actually want?

@vphantom
Copy link

Is there any other way to get the W3C's attention about this?

It's been over 5 years and we've been through one header change already (FP → PP) so clearly they either don't care or never even noticed this major design flaw which is costing everyone (interested in compliance) time to maintain the list of features, and bandwidth to send those headers to browsers.

A simple all=() ahead of the more specific permissions we do use (if any) would be fine and backwards-compatible.

@dimaqq
Copy link

dimaqq commented Mar 26, 2024

Is there any other way to get the W3C's attention about this?

☝🏻 easily, don't use this proposal, let it die.
If the origin servers don't send this header field, the browsers will not enforce it.
Someone will eventually come up with a better proposal, or a better concept.

@theherk
Copy link

theherk commented Mar 26, 2024

@dimaqq I think I get your point, but I don't think just throwing our hands up will do much either, as we still have to make these things work and abandoning CSP Permissions-Policy simply isn't going to happen. If browsers stopped supporting it, we'd be going the wrong direction. Better the proposal is ideally adopted at some point. If a better proposal exists or comes up, then that proposal can be adopted. In the meantime, this seems to be fairly well-liked.

@Gunni
Copy link

Gunni commented Mar 26, 2024

I don't think anyone here is talking about the content security policy since it has a sane default policy. The permission policy on the other hand does not which is what we are talking about here.

@theherk
Copy link

theherk commented Mar 26, 2024

Yes, I misspoke. But I still maintain that the abandoning the proposal without an alternative doesn't seem better than this proposal.

@vphantom
Copy link

In our case we're forced to output that header in order to pass basic security scans so I can't let it die. :( At best I could reduce the header to almost nothing, but that would defeat the purpose of promising to behave. As it stands, our header has 62 of the 66 known features explicitly disabled and I have to search for new features regularly. I could probably remove some benign stuff to bring it down to 20-30 but I'd still have to regularly hunt for new offenders.

There have been several well-designed, backwards-compatible suggestions here these past 6 years and yet not a peep from the W3C to at least acknowledge the issue. They even mention in https://www.w3.org/TR/permissions-policy/ that "The web platform provides an ever-expanding set of features" and yet still maintain that selectively disabling individual features we know about is appropriate.

It is somehow the webmaster's responsibility to discover new features as they arise and to add them to an ever-growing deny list in order to correctly promise good behavior and to help deny access to misbehaving third parties (included JS, PunchOut frame parents, etc.)

@yannikbloscheck
Copy link

The header obviously gets way too big, if you actually want to disable most things. It's just frustrating. This really needs to be finally solved.
It's obvious a default directive is needed. No matter if it actually will be called default=(), all=() or anything else.
I really can't understand why this is being ignored for so long. Apparently this has been discussed and requested for over five years now...

@Seirdy
Copy link

Seirdy commented Mar 31, 2024

The header obviously gets way too big, if you actually want to disable most things. It's just frustrating. This really needs to be finally solved. It's obvious a default directive is needed. No matter if it actually will be called default=(), all=() or anything else. I really can't understand why this is being ignored for so long.

@yannikbloscheck If you read the discussions you cited, you would know that a plain default-deny directive would not be forwards-compatible and is therefore not an option. Defining new meta-directives with specific static inheritance rules is a better option.

@yannikbloscheck
Copy link

@yannikbloscheck If you read the discussions you cited, you would know that a plain default-deny directive would not be forwards-compatible and is therefore not an option. Defining new meta-directives with specific static inheritance rules is a better option.

@Seirdy I read your ideas.
The directive groupings for feature areas is a good idea, but practically those group directives would need to be extendable, which would lead to the same problems. I still hope such groups will be implemented though, because it's a great idea anyway.
The directive groupings by point in time (or probably rather version number) would solve many of these problems. Web developers still would need to update the policy regularly to deny as much as possible. Also browser developers would need to agree every time what is included in each version. Also not a bad idea either.

A default directive would simply leave the choice to the developer though.
Maybe I don't care about being forwards compatible with any new (or even existing) access. Then I choose default=(). Maybe I want to allow anything new for my site by default. Then I could choose default=(self) etc.
If I want to be a responsible developer, I have to keep myself updated with what is added to this header in all cases anyway.
There are many other security headers that a web developer can use to shoot their future self in the foot by using too restrictive choices. But all those headers still exist anyway.

I can still understand the fears the browser developers have about this in regards to forward-compatibility. Especially as they don't really have to worry about all the extra unnecessary traffic the current solution causes. The browser developers probably would be forced to heavily communicate some new directives and have longer roll-out times. Still any developer worried about having anything break ever could just leave the default directive out or set a very permissive one. The documentation by the browser developers etc. could for example suggest default=(self) as the best choice.

The main thing though is that this has been a problem for over five years. While there has been much discussion about whatever problems might happen with any solution in the future, there has been a real problem (incredible header bloat) in practice for all this time and it isn't getting solved.

@marcoscaceres
Copy link
Member

@clelland and I met today and we have a new concrete proposal to allow documents to turn off all features with a default allowlist of 'self':

  • We introduce a boolean-like feature-name (yet to be named, but see bikeshed below) that behaves as a boolean flag.
  • When present, it causes the page to have the same permission policies as a third-party iframe.
  • The flag takes no values, it's just a boolean
  • For both backwards compatibility and for overrides, this can be overridden by specifying an allowlist for features which are disabled by this flag
  • For forwards compatibility, this doesn't affect any features with a default allowlist of '*'

Name bikeshed:

  • treat-as-remote-origin
  • treat-as-third-party
  • treat-as-untrusted
  • untrusted

We are not sure about "third-party", because it implies a lot of other things if you were to read that literally. We kinda like "untrusted" because it reads kinda nice:

Permissions-Policy: untrusted, geolocation=(self)

@PeteX
Copy link

PeteX commented Oct 18, 2024

It's great that this is moving forward, thanks for coming up with this proposal.

One question—will browser developers ever want to change the set of permissions that are applied to third-party iframes? Recently they have become more locked down, to reduce cross-site tracking of users. If that trend continues and there is a wish to withdraw some of the permissions we're discussing here, it could lead to divergence between the "untrusted" permissions policy and the permissions that are granted to third-party iframes in practice.

I'm genuinely not sure if this is an issue or not, so I will now leave this for people more qualified than I am. 🙂

@annevk
Copy link
Member

annevk commented Oct 18, 2024

The concern @PeteX raises is one I share and I continue to believe we should not do this therefore. Although it is somewhat painful, it is possible to enumerate all the permissions and disable them. That in turn allows us to make further tweaks to what is allowed in nested documents more easily, such as possibly gating the <input type=file> dialog behind a permission.

@jvoisin
Copy link

jvoisin commented Oct 18, 2024

The concern @PeteX raises is one I share and I continue to believe we should not do this therefore. Although it is somewhat painful, it is possible to enumerate all the permissions and disable them. That in turn allows us to make further tweaks to what is allowed in nested documents more easily, such as possibly gating the dialog behind a permission.

Is it though? I don't know all the permissions on top of my head, and I shouldn't be required to to simply configure my website as a regular one. Moreover, even if I somehow found a somehow comprehensive list like allow="accelerometer 'none'; ambient-light-sensor 'none'; autoplay 'none'; battery 'none'; bluetooth 'none'; browsing-topics 'none'; camera 'none'; ch-ua 'none'; display-capture 'none'; domain-agent 'none'; document-domain 'none'; encrypted-media 'none'; execution-while-not-rendered 'none'; execution-while-out-of-viewport 'none'; gamepad 'none'; geolocation 'none'; gyroscope 'none'; hid 'none'; identity-credentials-get 'none'; idle-detection 'none'; keyboard-map 'none'; local-fonts 'none'; magnetometer 'none'; microphone 'none'; midi 'none'; navigation-override 'none'; otp-credentials 'none'; payment 'none'; picture-in-picture 'none'; publickey-credentials-create 'none'; publickey-credentials-get 'none'; screen-wake-lock 'none'; serial 'none'; speaker-selection 'none'; sync-xhr 'none'; usb 'none'; web-share 'none'; window-management 'none'; xr-spatial-tracking 'none'", maybe it'll be outdated in 2 months when someone adds yet another weird permission, who knows. Also, maybe I lied and the list isn't complete, can you find out what's left out? CSP is a security control, it should be straightforward to audit: the current "spell everything out and hope you don't forget anything" state is everything but.

@annevk
Copy link
Member

annevk commented Oct 18, 2024

maybe it'll be outdated in 2 months when someone adds yet another weird permission

But that is the point. Your website might be making use of a feature that the weird permission would gate. If you opted into everything your website would break and end users would be sad. This is a risk we have been willing to take at times for third-party content, but this would extend the risk to every website, making it far less tenable to do.

@jvoisin
Copy link

jvoisin commented Oct 18, 2024

I'd argue that if you want to make use of the latest new feature, it's pretty easy to add ; new-shiny-feature 'self', versus putting the burden on every single other website that doesn't use it. Moreoever, even if the majority of websites would like to use this feature, they'll still fail-open for the next added one, which is a terrible idea security-wise: expanding attack surface for everyone to save the vast minority making use of exotic features like gamepad on their website from adding 3 words to their CSP configuration is worrying at best.

@yahesh
Copy link

yahesh commented Oct 18, 2024

It's really saddening to see that even half a decade later the discussion still evolves around the same thing.

As long as this fails open when set, it's not a security header (even though different security scanners started to handle it as such). As long as there's no deny-all possibility, I'll continue to tell everyone off who expects this header to be implemented as a form of security improvement.

@ewanm89
Copy link

ewanm89 commented Oct 19, 2024

The concern @PeteX raises is one I share and I continue to believe we should not do this therefore. Although it is somewhat painful, it is possible to enumerate all the permissions and disable them. That in turn allows us to make further tweaks to what is allowed in nested documents more easily, such as possibly gating the <input type=file> dialog behind a permission.

This fails security 101 of The principle of least privilege I therefore hand you a fail in security 101, the idea here is to deny the vast amount of permissions by default thereby gating most of them you can still enable them.

I do think they should be a deny all and not just some.

The principle of least privilege is not a nice thing, it is how you build secure systems, and developers can always enable to features they use and need. We already need to spin up a local webserver to get a secure context for testing, we are already doing this work. We should have a way to default to none so we can't miss one by mistake, or because browser A implemented something I don't know about because browser B is my prefered browser. If there is a problem I can enable the permission.

@darioseidl
Copy link

maybe it'll be outdated in 2 months when someone adds yet another weird permission

But that is the point. Your website might be making use of a feature that the weird permission would gate. If you opted into everything your website would break and end users would be sad. This is a risk we have been willing to take at times for third-party content, but this would extend the risk to every website, making it far less tenable to do.

This point has been made, and countless people have voiced their opinion already that it does not apply to them: I want to author a website that is secure and works now. I want it to be secure in the future, but I don't mind if it breaks in the future.

If browsers introduce a permission policy for an existing feature that my website is using already, one of the following things will happen:

  1. I will read about it before it is introduced, and I can decide whether I need that feature or not. It's all good. As developers of any software, we already have to stay informed to keep things working, given that software changes constantly. It's not the end of the world.

  2. I miss the news about the policy and my website breaks (or rather, I would expect some specific part of the website to stop working). My users are sad. But I test my website too, and notice that something has stopped working. Or my sad users tell me, please fix this. So I fix it. It's not the end of the world.

If somebody doesn't want that to happen to them, they simply don't need to use the proposed deny-all policy.

Please just introduce a deny-all permissions policy. It's the sane thing to do.

@PeteX
Copy link

PeteX commented Oct 20, 2024

I'm sorry! 😢 I posted what was meant to be a question about a minor detail, then went away for the weekend. Coming back it looks as though I've managed to derail this proposal again, which wasn't my intention at all—I actually support it.

It's a valid concern that websites might break when new permissions are specified. I think there are solutions, though. Suppose we started with deny-all-v1, which denies all permissions specified at the present time. When the set of permissions changes, we create deny-all-v2, and so on.

Potentially there would end up being a lot of versions, but that's not a problem. The browser just needs to know which "generation" each permission belongs to; this tells it the version of deny-all which is required for it to be disabled. Web developers will normally just pick the latest version of deny-all for their project, since they want to deny everything which is specified at that time.

@vphantom
Copy link

There is nothing inherently wrong with a deny-all. Web sites routinely need updating to keep up with current standards as browsers evolve, and the use of deny-all itself being opt-in makes webmasters take responsibility explicitly for watching out for future issues. Versions would bring us right back to having to discover and disable new versions proactively.

@Gunni
Copy link

Gunni commented Oct 20, 2024

Why are new APIs not denied by default?

@kifd
Copy link

kifd commented Oct 20, 2024

... since they want to deny everything which is specified at that time.

No, I want to deny everything that I've not explicitly asked for, regardless of if that permission exists now or in the future. I know what features the websites I serve up need, they're the ones I enable - I really don't want to continually look out for an ever increasing laundry list of permission features that need disabling.

I just can't see how a choice of "deny all except a,b,c features" would manage to break a site in the future, without the website itself changing. At that point I can simply add the needed "x,y,z features" to the directives whitelist and be thankful that I haven't had to waste my time disabling "d,e,f,g,h ... features" in the meantime.

Besides, as originally pointed out by OP six years ago, it's how the Content-Security-Policy works and nobody's proposing to change that to this state of affairs.

@clelland
Copy link
Collaborator

@annevk, I think that we can do this safely, and that something shaped roughly like the proposed

Permissions-Policy: untrusted

is a reasonable way to do it.

The model I have is that there are a set of policy-controlled features which, by default, we will deny to cross-origin embedded content, on the basis that we don't trust it. This applies to any cross-origin page loaded into an <iframe> with no allow attribute at all.

However, we expect that such embedded content will continue to fundamentally work. We wouldn't choose to put an existing feature under policy-control (like the above-mentioned strawmen 'images' or 'scripts') if we believed that it would break existing embedded content. Any addition like that could only happen after very careful consideration of backwards-compatibility and interop. That's already a promise we have to make, because of existing embedded content, not because of this proposal.

This proposal just allows sites to use a header directive to opt in to that same mode for their top-level documents.

The risk to the site should be roughly the same as being used as embedded content -- and is actually strictly less, since a site which can set its own headers can also mitigate any breakage by adjusting those headers, unlike a third-party embed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature question Questions and issues around specific policy-controlled features
Projects
None yet
Development

No branches or pull requests