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

laukstein opened this issue Jul 17, 2018 · 61 comments

Proposal: define default for all #189

laukstein opened this issue Jul 17, 2018 · 61 comments


Copy link

@laukstein laukstein commented Jul 17, 2018

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.

Copy link

@CharlesStover CharlesStover 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.


Copy link

@nico3333fr nico3333fr commented Jul 22, 2018

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


Copy link

@eeeps 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.


Copy link

@olmari 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.


Copy link

@ojanvafai ojanvafai commented Aug 8, 2018

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.


Copy link

@olmari 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.


Copy link

@clelland clelland commented Aug 27, 2018

@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.


Copy link

@olmari 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...


Copy link

@clelland clelland commented Aug 27, 2018

@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'.


Copy link

@valtlai 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.


Copy link

@laukstein laukstein commented Aug 28, 2018

@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


Copy link

@clelland clelland commented Aug 29, 2018

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.


Copy link

@AfroThundr3007730 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.


Copy link

@sstelfox 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.


Copy link

@yahesh 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 blacklist and that has to be modified whenever a vendor introduces a new value. Security filters should work as whitelists 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.


Copy link

@ewanm89 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.


Copy link

@triblondon triblondon commented Feb 7, 2019

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.


Copy link

@ExE-Boss 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.


Copy link

@Jamesernator Jamesernator commented Feb 17, 2019

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.


Copy link

@ojanvafai ojanvafai commented Feb 28, 2019

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 ( Repeated violations will result in being blocked from commenting on the repository.


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

@sstelfox sstelfox commented Feb 28, 2019

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 this to New input in FP Engagement May 13, 2019
@pabrai pabrai moved this from New input to Questions in FP Engagement May 13, 2019
Copy link

@Jamesernator 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.


Copy link

@xdevs23 xdevs23 commented May 5, 2020

You are assuming (and every one know the result of when you assume something), that browser will never consume that service at any time. Which is a pretty big assumption (I consider having an API that device sends data too, and then user logs into via a web interface for later display and processing of data).

Point still stands, APIs don't need all of those headers. You don't need to specify Feature-Policy, Content-Security-Policy etc. because that only works with HTML, not APIs. What you should specify are CORS and HTTPS-related headers.


Copy link

@oliverjanik oliverjanik commented May 6, 2020

While you're technically correct @xdevs23 the pentesting companies apply blanket scanners that flag missing headers and then non-technical management gets reports of security "vulnerabilities" that become top priority and you end up back here in this thread.


Copy link

@xdevs23 xdevs23 commented May 6, 2020

While you're technically correct @xdevs23 the pentesting companies apply blanket scanners that flag missing headers and then non-technical management gets reports of security "vulnerabilities" that become top priority and you end up back here in this thread.

That's a fair point. But in that case there is no reason to worry about header size in general. Only Feature-Policy is one that requires maintenance (features keep getting added or removed).


Copy link

@ewanm89 ewanm89 commented May 6, 2020

It is entirely possible for a user to put the URL in a browser for a Web API even if a computer is more likely to consume it, and for the api to output data in a html based format for other use. There are reasons pentesting scanners always flag on this header, if these headers are to have any real protection, they must always be used, that way you don't miss some odd use case cause you aren't using it that way.

Hell has everyone at W3C forgotten that XHTML, XML and XSLT exist?


Copy link

@dimaqq dimaqq commented May 12, 2020

Here's my attempt for a battened down admin site: accelerometer 'none'; ambient-light-sensor 'none'; autoplay 'none'; battery 'none'; camera 'none'; display-capture 'none'; document-domain 'none'; encrypted-media 'none'; fullscreen 'none'; geolocation 'none'; gyroscope 'none'; legacy-image-formats 'none'; magnetometer 'none'; microphone 'none'; midi 'none'; oversized-images 'none'; payment 'none'; picture-in-picture 'none'; publickey-credentials 'none'; sync-xhr 'none'; unoptimized-images 'none'; unsized-media 'none'; usb 'none'; vibrate 'none'; vr 'none'; wake-lock 'none'; xr-spatial-tracking 'none';

What's wrong with that:

  • slow, adds 558 bytes (uncompressed) 259 bytes (gzip) 226 bytes (br) to the first response
  • too long for some (👉Azure CDN) servers
  • insane to maintain


Copy link

@Malvoz Malvoz commented May 12, 2020

Off-topic: @dimaqq FYI vibrate isn't defined in any spec, nor implemented in any browser so you could remove that, publickey-credentials was renamed publickey-credentials-get, and vr is deprecated as the WebVR API was replaced with the WebXR Device API ("xr-spatial-tracking").


Copy link

@sam-spain sam-spain commented Sep 17, 2020

Is there a more maintainable way to do the following for Apache server?
Header always set Feature-Policy "ambient-light-sensor 'none'; autoplay 'none'; accelerometer 'none'; camera 'none'; display-capture 'none'; document-domain 'none'; encrypted-media 'none'; fullscreen 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'; midi 'none'; payment 'none'; picture-in-picture 'none'; sync-xhr 'none'; usb 'none'; wake-lock 'none'; xr-spatial-tracking 'none'"

It seems really silly to have this. Also means any new features will need to be added.


Copy link

@laukstein laukstein commented Sep 17, 2020

Doe to policies list repeatedly growing, in order to handle it reasonable, the policies should be grouped in "categories" and maybe also "sub-categories" allowing to use like:

Permissions Policy sensors 'none'; microphone 'self'; dom-changes 'none'; fullscreen ''

Groups and sub-groups: e.g. sensors (media), JavaScript (DOM manipulations, workers), etc.


Copy link

@clelland clelland commented Sep 17, 2020

Groups are something that's been considered, that hasn't been specced yet -- mostly because I haven't gotten around to it, but it's certainly becoming a bigger issue. Adding client hints to the set will expand this list quite a bit. It would certainly be more ergonomic to have a way to group features together.

I suspect that there are probably two different things we could do there: One is to provide less-granular control, like in #189 (comment), to configure features in well-defined groups, where there might even be a top-level group for all features (but see below)

The other, that I mentioned in #189 (comment), would be to provide a single setting that essentially says "treat this as an untrusted document, as if it were loaded in a cross-origin frame". That setting would ensure that the basic platform features continue to work, but that none of the more powerful features are available. Anything which is restricted by default in cross-origin frames would be blocked.

I like the idea of groups, but they would need to be well-defined, and there would have to be a way to ensure that there was no overlap (although nested groups might be possible). We'd need to be very deliberate about which group each feature belonged in, to avoid any ambiguities if one group is disabled while another is enabled.


Copy link

@mikeoptics mikeoptics commented Oct 29, 2020

Whilst I agree the whitelist approach makes the most sense, it would be a www breaking change.
I would propose that a new header be implemented that is a whitelist version of the previous (Permitted-Permissions-Policy?)
All new/upcoming policies would be disabled by default and would need to be defined under this new policy. If the policy is present, ignore the older 'Feature-Policy/Permissions Policy'. I would also reverse the order so that * and 'self' came first.

This would allow for older systems to not break and would also not subject them to the security concerns of newer features.
As for the directives:


e.g. all=*

sensor: [ accelerometer, ambient-light-sensor, gyroscope, magnetometer ]
capture: [ camera, geolocation, usb, vibrate, microphone, vr, display-capture, midi]
system: [wake-lock, battery]
html: [xr-spatial-tracking, autoplay, fullscreen, encrypted-media, legacy-image-formats, oversized-images, payment, picture-in-picture, sync-xhr, unoptimized-images, unsized-media ]
authentication: [publickey-credentials]
legacy: [document-domain]

group selector. e.g. self = [sensor], [html]; all = [authentication]; = [system];


e.g. self = battery

A complete policy would look like this:
Permitted-Permissions-Policy: all = [html]; self = geolocation, [sensor]; = geolocation, payment, [authentication];


Copy link

@ghost ghost commented Jan 10, 2021

If a conscious decision is made by an entity to use a whitelist approach, one should infer from that their willingness to manage the policy so that their site remains functional.
Removing this ability weakens the security aspects of the header making it a counterproductive decision.

So my proposal:
By default the rule should always prepend *=default, subsequent policy declarations override that, e.g.: *=().
Wildcards could also provide group-like functionality, so sensor-accelerometer, sensor-ambient-light and other sensor functionalities could be defined as sensor-*.
If I wanted to make the header as small as possible I could think of something like *=(); (sensor-* media-autoplay)=self; sensor-gyroscope+=("" ""); sensor-ambient-light=().


Copy link

@vphantom vphantom commented Jan 11, 2021

Quick question: why would such a feature whitelist come with an entirely new syntax to parse and produce where the general format of Content-Security-Policy already exists for a very similar purpose? For example, perhaps:

Permissions-Policy: default 'none'; geolocation 'self'; media-autoplay 'self'


Copy link

@ghost ghost commented Jan 11, 2021

Quoting the explainer document:

A policy which would previously have been expressed as:

Feature-Policy: fullscreen 'self';
    geolocation *; camera 'none'

would now look like:

Permissions-Policy: fullscreen=(self "" ""),
    geolocation=*, camera=()

For my proposal I took the new format and made minor alterations to its syntax to shorten the length of the header while making it easier to maintain and understand at a glance, at the same time also offering a solution for implementing feature groups.

In the current format the policy I described, provided setting all to none was a possibility
*=(); (sensor-* media-autoplay)=self; sensor-gyroscope+=("" ""); sensor-ambient-light=()
would look like this:
*=(), media-autoplay=self, sensor-gyroscope=(self "" ""), sensor-sensor-1=self, sensor-sensor-2=self, ..., sensor-sensor-n=self


Copy link

@gapple gapple commented Jan 12, 2021

The header format is Structured Field Values for HTTP (which didn't exist when CSP was defined). (See 5. Serialization)

(sensor-* media-autoplay)=self would not work with the Structured Field Values syntax, and would need to be specified as sensor-*=self; media-autoplay=self


Copy link

@ghost ghost commented Jan 13, 2021

Yes, unless there is a change to allow inner lists as keys, for which there could be a need now.


Copy link

@runthis runthis commented Mar 23, 2021

I know this discussion is leaning towards 3 years old now. Does it seem possible in 2021 to disable all by default? On my portfolio website I don't foresee needing any permissions and would happily enable them one by one if I did (much like how CSP works).


Copy link

@sandorvasas sandorvasas commented May 12, 2021

I've just come across this header and the intuitive way to me would be to disable all by default and explicitly enable stuff in the header. I'm surprised this is an unresolved issue.


Copy link

@olmari olmari commented May 13, 2021

Mine 2 cents is still basically as @sandorvasas said, in additition with possibility in header to define default that caters to everything. Thus if nothing is done, nothing happends, if site admin has defined default then that is used if no direct match exist.


Copy link

@Seirdy Seirdy commented Aug 24, 2021

Adapting something I posted on Fedi a few days ago:

Every new web feature wants its own entry in this massive chonker of a header, and there’s no one place to view all the directives. Here’s where we’re at now:

Permissions-Policy: accelerometer=(),ambient-light-sensor=(),attribution-reporting=(),autoplay=(),battery=(),camera=(),clipboard-read=(),clipboard-write=(),conversion-measurement=(),cross-origin-isolated=(),direct-sockets=(),display-capture=(),document-domain=(),encrypted-media=(),execution-while-not-rendered=(),execution-while-out-of-viewport=(),focus-without-user-activation=(),fullscreen=(),gamepad=(),geolocation=(),gyroscope=(),hid=(),idle-detection=(),interest-cohort=(),magnetometer=(),microphone=(),midi=(),navigation-override=(),otp-credentials=(),payment=(),picture-in-picture=(),publickey-credentials-get=(),screen-wake-lock=(),serial=(),shared-autofill=(),speaker-selection=(),storage-access-api=(),sync-script=(),sync-xhr=(),trust-token-redemption=(),usb=(),vertical-scroll=(),wake-lock=(),web-share=(),window-placement=(),xr-spatial-tracking=()

That one-line view doesn't quite capture the current state of things. Here's a multiline list of current directives:

     1	accelerometer
     2	ambient-light-sensor
     3	attribution-reporting
     4	autoplay
     5	battery
     6	camera
     7	clipboard-read
     8	clipboard-write
     9	conversion-measurement
    10	cross-origin-isolated
    11	direct-sockets
    12	display-capture
    13	document-domain
    14	encrypted-media
    15	execution-while-not-rendered
    16	execution-while-out-of-viewport
    17	focus-without-user-activation
    18	fullscreen
    19	gamepad
    20	geolocation
    21	gyroscope
    22	hid
    23	idle-detection
    24	interest-cohort
    25	magnetometer
    26	microphone
    27	midi
    28	navigation-override
    29	otp-credentials
    30	payment
    31	picture-in-picture
    32	publickey-credentials-get
    33	screen-wake-lock
    34	serial
    35	shared-autofill
    36	speaker-selection
    37	storage-access-api
    38	sync-script
    39	sync-xhr
    40	trust-token-redemption
    41	usb
    42	vertical-scroll
    43	wake-lock
    44	web-share
    45	window-placement
    46	xr-spatial-tracking

The above example excludes client-hints permissions which allow delegating permission to read client hints to other domains.

You can view all the perms supported by the Chrome DevTools Protocol at once. A subset is documented in a non-normative companion document to the main Permissions-Policy spec.

I found some scattered documentation for a few perms that have been implemented by Chromium:

Pages that don't use any sensitive APIs should be able to just opt-out of this permissions just like what sandbox allows. A default directive would allow these pages to switch to selective-allowing while still letting others ignore it and perform blocking on a case-by-case basis.

HTTP headers are already a significant chunk of total page weight, even with HPACK. This header is easily the biggest on simple pages.


Copy link

@dimaqq dimaqq commented Aug 25, 2021


I feel that the feature creep will kill this entire proposal (not the defaults idea).
Everyone and their uncle can add yet another directive (floc, otp) which becomes otp-out for existing web sites as it is now.
(opt-in if the defaults idea becomes the norm)

My counter-proposal would be: majority (all?) of these features require client-side JavaScript, why not set up these restrictions using JavaScript as well?
Case in point would be requestStorageAccess for storage-access-api.


Copy link

@DanWin DanWin commented Aug 25, 2021

The main point of having a Permission Policy in place, is to restrict what you can do with JavaScript. Allowing to change the Permissions with JS would also allow 3rd party scripts to ask for permissions, which you may not agree with. Or in case of an XSS-like security breach, an attacker could inject some code that will ask for various permissions. So it absolutely makes sense to have a server-side generated header, which tells the browser exactly what it is allowed to make use of.
The only way that JS could have the same protection is, if you setup the policy as the very first thing, before any other JS is getting executed and from then on the policy can't be changed. This will be difficult to enforce though, especially when making use of frameworks that perhaps inject JS before you have a chance to hook in your own JS.

The current opt-out policy, makes it hard to stay up-to-date. New features will get added all the time, so a site operator wishing to opt out from all of these would have to update the header every once in a while.
But if we consider a default option to disable all features by default and only selectively enabling them, when needed, a site operator could define a strict rule of exactly the permissions the site needs. When new features become available, they are not suddenly going to be used by the site operator just because they exist. A developer would have to change the code and it would be an easy thing to then also update the header when necessary.


Copy link

@Seirdy Seirdy commented Aug 27, 2021

I admit that bundling every permission into one universal directive does expose a problem: a site that works with such a directive today might break tomorrow as a new permission is introduced for features the site uses.

I therefore propose simplifying the policy by following a different approach: group many related directives together.

  • All policies that involve accessing devices can be grouped under a devices directive. This can include:
    • accelerometer
    • ambient-light-sensor
    • battery
    • camera
    • gamepad
    • gyroscope
    • hid
    • magnetometer
    • microphone
    • midi
    • serial
    • speaker-selection
    • usb
    • xr-spatial-tracking
  • All policies that involve window-management, i.e. performing tasks that are normally handled by a window manager/compositor, can be grouped under a window-management directive. This can include:
    • fullscreen
    • picture-in-picture
    • window-placement
  • Policies that change how the browser prioritizes a webpage (e.g. regarding throttling, focus) can be grouped under a priority directive. This can include:
    • autoplay
    • cross-origin-isolated
    • execution-while-not-rendered
    • execution-while-out-of-viewport
    • focus-without-user-activation
    • sync-script
  • All policies that involve sending data between the UA and the OS can be grouped under a talks directive. This can include:
    • clipboard-read
    • clipboard-write
    • display-capture
    • otp-credentials
    • publickey-credentials-get
    • storage-access-api
    • web-share
  • Remaining policies that involve tracking that don't fall in the above categories (i.e., features explicitly made for forms of tracking, but not necessarily privacy-invasive if you ignore fingerprinting) can fall under a tracking directive. This can include:
    • conversion-measurement
    • interest-cohort
    • trust-token-redemption
  • All client-hints directives can fall under a ch directive.

I can't seem to come up with a good way to categorize the following directives:

  • direct-sockets
  • encrypted-media
  • idle-detection
  • navigation-override
  • payment
  • screen-wake-lock
  • shared-autofill
  • sync-xhr
  • geolocation
  • vertical-scroll
  • wake-lock

These directives are deprecated and can be excluded:

  • document-domain

I think that adding groups for devices, ch, and window-management shouldn't be as controversial as the rest. Just like default-src in the CSP, webpages could first specify their "defaults" this way and then specify individual overrides. This could significantly reduce the size and complexity of the header.

If this sounds like a good idea I could create a separate issue.


Copy link

@theherk theherk commented Nov 22, 2021

It still seems like, even if you use several groups, it should be the option of the site's administrator to choose explicitly to allow or disallow all features, even if that means a breakage when permissions are added. As long as it isn't the default, this makes sense.


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
FP Engagement
Linked pull requests

Successfully merging a pull request may close this issue.

None yet