This specification defines a mechanism that allows developers to selectively enable and disable use of various browser features and APIs.
This is a work in progress and may change without any notices.
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:
This specification defines a feature policy mechanism that addresses the above use cases.
SecureCorp Inc. wants to disable use of WebRTC and Geolocation APIs within their application. It can do so by delivering the following HTTP response header to define a feature policy:
Feature-Policy: {"disable":["webrtc","geolocation"]}
Unless specified otherwise, the default target is "`\*`", which means that the specified features will be disabled for all browsing contexts regardless of their origin.
SecureCorp Inc. wants to disable use of Geolocation API within all browsing contexts whose origin is "`https://example.com`". It can do so by delivering the following HTTP response header to define a feature policy:
Feature-Policy: {"disable":["geolocation"], "target":["https://example.com"]}
The target is a list of one or more origins, which can include the applications origin and any third-party origin.
SecureCorp Inc. is hosting an application on "`https://example.com`" and wants to disable WebRTC on its origin but enable it for a whitelisted embedee ("`https://other.com`"). It can do so by delivering the following HTTP response header to define a feature policy:
Feature-Policy: {"disable":["webrtc"], "target":["https://example.com"]}, {"enable":["webrtc"], "target":["https://other.com"]}
Some features are disabled by default in embedded contexts. The enable policy allows the application to selectively enable such features for whitelisted origins.
FastCorp Inc. wants to disable use of synchronous `script` elements, synchronous `XMLHttpRequest`'s and use of `document.write` within their application. It can do so by delivering the following HTTP response header to define a feature policy:
Feature-Policy: {"disable":["sync-xhr","sync-script","docwrite"]}
[[HTML5]] defines a [sandbox attribute] for `iframe` elements that allows developers to reduce the risk of including potentially untrusted content by imposing restrictions on content's abilities - e.g. prevent it from submitting forms, running scripts and plugins, and more. The [sandbox directive] defined by [[CSP2]] extends this capability to any resource, framed or not, to ask for the same set of restrictions - e.g. via an HTTP response header (`Content-Security-Policy: sandbox`). These mechanisms enable the developer to:
However, there are several limitations to the above mechanism: the developer cannot automatically apply a policy across all contexts, which makes it hard or impossible to enforce consistently in some cases (e.g. due to third-party content injecting frames, which the developer does not control); there is no mechanism to selectively enable features that may be off by default; the sandbox mechanism uses a whitelist approach which is impossible to extend without compatibility risk.
Feature Policy is intended to be used in combination with the sandbox mechanism (i.e. it does not duplicate feature controls already covered by sandbox), and provides an extensible mechanism that addresses the above limitations.
A feature policy may be applied to a [Window] or [WorkerGlobalScope] and consists of:
Each directive is a tuple consisting of:
The following sections define the set of known members in each JSON object describing the policy. Future versions of this document may define additional such members and user agents MUST ignore unknown members when parsing the object.
The OPTIONAL target member defines the scope in which the directive is enforced. The member's name is "`target`" and the recognized values are either an array of serialized origins which may contain the "`self`" keyword that refers to current global's origin, or the string "`\*`". If an unknown value is specified, or if no member named "`target`" is present in the object, the directive's target will be set to "`\*`".
The OPTIONAL disable member defines the disable policy for the directive. The member's name is "`disable`" and the value is a list of ASCII strings.
The OPTIONAL enable member defines the enable policy for the directive. The member's name is "`enable`" and the value is a list of ASCII strings. [response]
The Feature-Policy HTTP header field can be used both in the [response] (server to client) and a [request] (client to server) to communicate the feature policy. In the former case, the server is communicating the desired policy that should be enforced by the client, and in the latter, the client is communicating the policy that it will enforce.
The header's value is represented by the following ABNF [[!RFC5234]]:
Disable = 1#json-field-value
; See Section 2 of [[HTTP-JFV]], and Section 2 of [[RFC7159]]
When the user agent receives a `Feature-Policy` header field, it MUST process and enforce the serialized policy as described in . When the user agent [performs a fetch][fetching algorithm], it MUST advertise the active feature policy as described in .
Given a [response] (response) and [global object] (global), this algorithm returns a feature policy.
A [Document] may deliver a policy via one or more HTML [meta] elements whose [http-equiv] attributes are an [ASCII case-insensitive] match for the string "`Feature-Policy`". For example:
<meta http-equiv="Feature-Policy"
content='{"disable": ["webrtc"]},
{"enable":["geolocation"],"target":["https://example.com"}'>
The `meta` policy is processed as defined in and modifications to the [content][meta-content] attribute of a `meta` element after the element has been parsed MUST be ignored.
TODO: talk about effect of multiple policies
This section extends HTML's `meta` [pragma directives].
Feature policy state (http-equiv="feature-policy")Given a string (value) and [global object] (global) this algorithm will return a feature policy.
This section defines features and their effect when applied via a directive as part of a feature policy.
The following table summarizes features defined by this specification, by their corresponding keywords. This table is non-normative; the actual definitions are given in the following sections.
| Feature | Enable policy | Disable policy | Brief description | |
|---|---|---|---|---|
| top-level context | nested context | |||
| cookie | `\*` | `\*` | `null` | Controls access to `document.cookie`. |
| domain | `\*` | `\*` | `null` | Controls access to `document.domain`. |
| docwrite | `\*` | `\*` | `null` | Controls access to `document.write`, `document.writeln`. |
| ... | ... | ... | ... | ... |
| geolocation | `self` | `null` | `null` | Controls access to [Geolocation interface]. |
| midi | `self` | `null` | `null` | Controls access to [requestMIDIAccess method]. |
| notifications | `self` | `null` | `null` | Controls access to [Notification interface]. |
| payment | `self` | `null` | `null` | Controls access to [PaymentRequest interface]. |
| push | `self` | `null` | `null` | Controls access to [PushManager interface]. |
| sync-script | `\*` | `\*` | `null` | Controls use of synchronous `script` elements. |
| sync-xhr | `\*` | `\*` | `null` | Controls access to synchronous `XMLHttpRequest` API. |
| usermedia | `self` | `null` | `null` | Controls access to [NavigatorUserMedia interface]. |
| vibrate | `self` | `null` | `null` | Controls access to [vibrate method]. |
| webrtc | `\*` | `\*` | `null` | Controls access to [RTCPeerConnection interface]. |
partial interface Document {
[Feature=cookie] attribute USVString cookie;
};
The cookie keyword controls whether the [cookie attribute] is [exposed] for [current global object].
partial interface Document {
[Feature=domain] attribute USVString domain;
};
The domain keyword controls whether the [domain attribute] is [exposed] for [current global object].
partial interface Document {
[CEReactions, Feature=docwrite] void write(DOMString... text);
[CEReactions, Feature=docwrite] void writeln(DOMString... text);
};
The docwrite keyword controls whether the [document.write] and [document.writeln] methods are [exposed] for [current global object].
partial interface Navigator {
[Feature=geolocation] readonly attribute Geolocation geolocation;
};
The geolocation keyword controls whether the [Geolocation interface] ([[!GEOLOCATION-API]]) is [exposed] for [current global object].
partial interface Navigator {
[Feature=midi] Promise<MIDIAccess> requestMIDIAccess (optional MIDIOptions options);
};
The midi keyword controls whether the [requestMIDIAccess method] ([[!WEBMIDI]]) is [exposed] for [current global object].
[Constructor(DOMString title, optional NotificationOptions options),
Feature=notifications]
interface Notification : EventTarget {};
The notifications keyword controls whether the [Notification interface] ([[!NOTIFICATIONS]]) is [exposed] for [current global object].
[Constructor(sequence<PaymentMethodData> methodData, PaymentDetails details, optional PaymentOptions options),
SecureContext, Feature=payment]
interface PaymentRequest : EventTarget {};
The payment keyword controls whether the [PaymentRequest interface] ([[!PAYMENT-REQUEST]]) is [exposed] for [current global object].
partial interface ServiceWorkerRegistration {
[Feature=push] readonly attribute PushManager pushManager;
};
[Feature=push]
interface PushManager {};
The push keyword controls whether the [PushManager interface] ([[!PUSH-API]]) is [exposed] for [current global object].
The sync-script keyword controls use of synchronous `script` elements, as defined in . When this feature is disabled, such scripts are ignored by the user agent.
Given the following header:
Feature-Policy: {"disable":["sync-script"]}
The following HTML will not result in execution of `script1.js`, as it has neither a [`defer`] nor an [`async`] attribute. The remaining scripts will execute normally because they have their [non-blocking] flag set.
<script src="/script1.js"></script>
<script src="/script2.js" async></script>
<script src="/script3.js" defer></script>
<script>
const scriptEl = document.createElement("script");
scriptEl.src = "/script4.js";
document.body.appendChild(scriptEl);
</script>
The sync-xhr keyword controls use of synchronous `XMLHttpRequest` API, as defined in . When [open() method](xhr-open) is called with async argument set to false, an `InvalidAccessError` except will be thrown.
Given the following header:
Feature-Policy: {"disable":["sync-xhr"]}
The following JavaScript code will throw a `InvalidAccessError` exception:
var xhr = new XMLHttpRequest();
xhr.open("GET", "/foo", false);
[Exposed=Window, NoInterfaceObject, Feature=usermedia]
interface NavigatorUserMedia {
[SameObject] readonly attribute MediaDevices mediaDevices;
};
The usermedia keyword controls whether the [NavigatorUserMedia interface] ([[!MEDIACAPTURE-API]]) is [exposed] for [current global object].
partial interface Navigator {
[Feature=vibrate] boolean vibrate(VibratePattern pattern);
};
The vibrate keyword controls whether the [vibrate method] ([[!VIBRATION]]) is [exposed] for [current global object].
[Constructor(optional RTCConfiguration configuration), Feature=webrtc]
interface RTCPeerConnection : EventTarget {};
The webrtc keyword controls whether the [RTCPeerConnection interface] ([[!WEBRTC]]) is [exposed] for [current global object].
The disable policy allows a developer to turn off certain
features for a Document or Worker.
Given a list, this algorithm returns a list of features, which may be empty.
The enable policy allows a developer to turn on certain
features for a Document or Worker.
Given a list, this algorithm returns a list of features, which may be empty.
This document defines a set of algorithms which other specifications will use in order to implement the restrictions which Feature Policy defines. The integrations are outlined here for clarity, but those external documents are the normative references which ought to be consulted for detailed information.
Document and WorkerGlobalScope objects have
a Feature Policy List, which is either the empty set or a
feature policy. This property is the empty set unless
otherwise specified, and is populated via the algorithm that is called during the
"Initialising a new Document object" and "Run a Worker"
algorithms.
The "[prepare a script]" algorithm calls into algorithm to determine whether or not to execute a script, as follows:
Given a [response] (response) and a global object (global), this algorithm populates global's Feature Policy List
Given a string (feature) and a global object (global), this algorithm returns "`Disabled`" if feature should be considered disabled, and "`Enabled`" otherwise.
This monkey patches [fetching algorithm], by inserting the following steps after current step #4:
The `open() method` calls into the algorithm to determine whether or not to throw, as follows:
This section defines an extended attribute whose presence affects only the ECMAScript binding.
If the [Feature] [extended attribute] appears on an interface, partial interface, or an individual interface member, it indicates that the interface or interface member is subject to feature policy associated with the ECMAScript global environment's global object.
The [Feature] [extended attribute] must [take an identifier], which must be a [global name].
Whether a construct that the [Feature] [extended attribute] can be specified on is enabled by feature policy for global is defined as follows:
Whether a construct is enabled by feature policy for global influences whether it is [exposed] in a given ECMAScript global environment.
The permanent message header field registry should be updated with the following registration [[!RFC3864]]:
TODO