A partial archive of discourse.wicg.io as of Saturday February 24, 2024.

Intent to Migrate: Feature Policy

Ian_Clelland
2018-11-28

Intent to Migrate: Feature Policy

Working group decision to adopt

The Web Application Security WG has agreed to adopt this proposal. (Mailing list thread split over two months; both links provided here for completeness)

https://lists.w3.org/Archives/Public/public-webappsec/2018Oct/0040.html

https://lists.w3.org/Archives/Public/public-webappsec/2018Nov/0005.html

Proposal

Summary

Feature Policy provides a mechanism for defining "features" on the web platform, and a uniform way for site authors to declare which of these features should be available on their pages, and on the documents they embed.

Motivation and Use Cases

From the introduction in the spec (https://wicg.github.io/feature-policy/#introduction):

The web-platform provides an ever-expanding set of features and APIs, offering richer functionality, better developer ergonomics, and improved performance. However, a missing piece is the ability for the developer to selectively enable, disable, or modify the behavior of some of these browser features and APIs within their application:

  1. The developer may want to selectively disable access to certain browser features and APIs to "lock down" their application, as a security or performance precaution, to prevent own and third-party content executing within their application from introducing unwanted or unexpected behaviors within their application.
  2. The developer may want to selectively enable access to certain browser features and APIs which may be disabled by default - e.g. some features may be disabled by default in embedded context unless explicitly enabled; some features may be subject to other policy requirements.
  3. The developer may want to use the policy to assert a promise to a client or an embedder about the use—or lack thereof—of certain features and APIs. For example, to enable certain types of "fast path" optimizations in the browser, or to assert a promise about conformance with some requirements set by other embedders - e.g. various social networks, search engines, and so on.

#1 is currently only possible through iframe sandboxing, and only for those features which are covered by that. Adding new features to that set is very difficult due to the opt-out nature of the sandbox.

#2 is either handled on with per-feature mechanisms (like <iframe allowfullscreen>) or through developers explicitly passing data or delegating control of features through something like postMessage. There is no standard mechanism for simply making the feature available in child frames.

#3 is currently not possible at all.

Compatibility Risk

As a "meta-feature" of sorts, removing feature policy from a web which has adopted it would have different effects, depending on the features which end up relying on it. The end result would likely be a return to the current ad-hoc feature availability state that we have today.

Features with a default allowlist of * would likely become available to all web content with no other restrictions (except for those which are also subject to iframe sandbox restrictions, which would still apply).

For permission-gated features, we would probably end up coming up with a new model for permission delegation, or reverting to a state where subframes are allowed to request permission going back to quire the specs which define features to either come up with new ways of allowing use in subframes

Other powerful features (those with a default allowlist of 'self') would likely go back to being allowed only in top-level documents, and not available in subframes at all, unless, like fullscreen, they implement their own delegation mechanism.

Current Support:

Ongoing technical constraints

What technical constraints will be added to user agents implementing this feature?

User agents will need to recognize the feature policy header and iframe attributes, and to construct policies, and check them when various features are requested by web content.

Will this feature be supported in all environments (desktop, mobile, tablets, TV, eBooks, automotive, etc.)?

Ideally, yes.

Link to implementation experience and demos

Demos:

YouTube embeds using this for autoplay and encrypted-media (No URL, but select "embed" after clicking "share" on any video on youtube.com):

<iframe width="560" height="315" src="https://www.youtube.com/embed/igHvSUrLqXc" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

The YouTube JS API uses this as well; instructions at https://developers.google.com/youtube/iframe_api_reference#Loading_a_Video_Player

AMP uses Feature Policy to disable synchronous XHR in ad iframes: https://github.com/ampproject/amphtml/pull/14481

Data

As of November 2018, the iframe ‘allow’ attribute is being used in approximately 14% of all page loads, as measured by Chrome’s opt-in user metrics.

Of these, much of the usage is for the features ‘encrypted-media’ and ‘autoplay’ (roughly 35% each), with significant usage (between 1.5 and 10% each) by ‘accelerometer’, ‘camera’, ‘fullscreen’, ‘geolocation’, ‘gyroscope’, ‘microphone’, ‘midi’, ‘picture-in-picture’ and ‘sync-xhr’.

Security and Privacy

See https://wicg.github.io/feature-policy/#privacy-and-security for the more complete writeup. From that section:

"This specification standardizes a mechanism for an embedding page to set a policy which will be enforced on an embedded page. Similar to iframe sandbox, this can be done without the express permission of the embedded page, which means that behaviors of existing features can be changed in published web sites, by embedding them in another document with an appropriate container policy.

As such, the biggest privacy and security concerns are:

  • Exposure of behavior in a cross-origin subframe to its embedder
  • Unanticipated behavior changes in subframes controlled by the embedder

To a degree, these concerns are already present in the web platform, and this specification attempts to at least not make them needlessly worse."

Accessibility

This feature can be used to control access to accessibility features (see proposal at https://github.com/WICG/feature-policy/issues/175, for instance,) but does not otherwise intersect with accessibility concerns.

Internationalization

This feature does not impose any internationalization requirements on implementers or site authors.

mikewest
2018-11-28

With my webappsec chair’s hat on, this LGTM.

cwilso
2018-11-29

LGTM. Let me know which org to transfer it to.

Ian_Clelland
2018-11-30

On the github side, I presume it gets transferred to the w3c org – I’m not sure if it should be renamed webappsec-feature-policy as part of that; all of the other repos seem to use that prefix.

@mikewest, do you know?

wseltzer
2018-12-01

I just created https://github.com/w3c/webappsec-feature-policy for it. We can blow that away if it’s easier to transfer directly.

Ian_Clelland
2018-12-03

It looks like we may have to do it in two steps – (1) migrate to w3c/feature-policy, and then (2) rename to w3c/webappsec-feature-policy.

(actually, I suppose we can do it the other way around, too – I don’t know if it matters, but we could rename to wicg/webappsec-feature-policy, and then move that to w3c.)

@wseltzer, I don’t think we can move issues and pull requests into that empty repo, we’ll probably have to blow it away so that we can use the name when we rename in step 2.

Anonymous2292900
2022-08-12

We could be warned with a popup about the site’s permissions just like you install an android app and in this case as I show here the google chrome webauthn popup as:

<script>
function confirmOkay() {
   var result = window.prompt("Permissions-Policy: geolocation?", "Yes");
   var text;
   if(result === null){
      text = "policy geolocation cancel..."
   }else{
      text = "policy geolocation(true): " + result;
   }
   var resultDiv = document.getElementById('result')
   resultDiv.innerHTML = text;
}
</script>

<input type="button" value="Permissions-Policy: geolocation?" onclick="confirmOkay()"/>
<div id="result">Permissions-Policy: geolocation=*.</div>