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 Feature-Policy HTTP [response] header field is used to deliver a feature policy from a server to client. 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]]
The policy is parsed as defined in , and the header’s value is interpreted as an array of JSON objects, as described in Section 4 of [[!HTTP-JFV]].
The policy MUST be delivered via an HTTP response header field to be processed by the client; the client MUST ignore any policy set via `meta` element's `http-equiv` attribute.
The feature policy needs to be set before the response is processed and before any subresource requests are initiated. Once active the policy also needs to apply for the lifetime of the document and is not allowed to be modified at runtime. Due to these requirements, `meta` element cannot be used to set the policy.
The following sections define the set of known members in each JSON object the header’s value defines. Future versions of this document may define additional such members, and user agents MUST ignore unknown members when parsing the header.
The OPTIONAL target member defines the scope in which the directive is enforced. The member's name is "`target`" and the recognized are either an array of serialized origins, 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.
Given a [response] (response) and a [request] (request), this algorithm returns a feature policy.
modern
", and the [origin] of response’s
[url] is not [potentially trustworthy].Given a string (value) this algorithm will return a feature policy.
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 valid disable features, which may be empty.
This section defines the list of valid disable features and their effect when applied via a directive as part of a feature policy.
Disables `document.cookie`: when present, the attribute's getter and
setter will throw a SecurityError
.
Given the following header:
Feature-Policy: {"disable":["cookie"]}
The following JavaScript code will throw a `SecurityError` exception:
document.cookie = "a=b;Secure;SameSite"; alert(document.cookie);
Disables `document.domain`: when present, the attribute's getter and
setter will throw a SecurityError
.
Given the following header:
Feature-Policy: {"disable":["domain"]}
The following JavaScript code will throw a `SecurityError` exception:
document.domain = "example.com"; alert(document.domain);
Disables `document.write`: when called, throws "`NotSupportedError`" `DOMException`.
Given the following header:
Feature-Policy: {"disable":["docwrite"]}
The following JavaScript code will throw a `NotSupportedError` exception:
document.write("...");
Disables Geolocation API. [[!GEOLOCATION-API]]
Disables Web MIDI API. [[!WEBMIDI]]
Disables Notification API. [[!NOTIFICATIONS]]
Disables Push API. [[!PUSH-API]]
Disables synchronous `script` elements. When this policy is set, 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>
Disables synchronous `XMLHttpRequest` API: when [open() method](xhr-open) is called with async argument set to true, 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", true);
Disables WebRTC. [[!WEBRTC]]
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.
Document
object" and "Run
a Worker" algorithms.
`document.cookie`'s getter and setter algorithms call into the algorithm to determine whether or not to throw, as follows:
On getting:
- If the document is a cookie-averse Document object, return the empty string.
- If the document's origin is an opaque origin, throw a "`SecurityError`" `DOMException`.
- If the algorithm returns "`Disabled`" when executed upon "`cookie`" and the document's global object, throw a "`SecurityError`" `DOMException`.
- Otherwise the user agent must return the cookie-string for the document's URL for a "non-HTTP" API, decoded using UTF-8 decode without BOM.
On setting:
- If the document is a cookie-averse Document object, then the user agent must skip the remaining substeps.
- If the document's origin is an opaque origin, throw a "`SecurityError`" `DOMException`.
- If the algorithm returns "`Disabled`" when executed upon "`cookie`" and the document's global object, throw a "`SecurityError`" `DOMException`.
- Otherwise, the user agent must act as it would when receiving a set-cookie-string for the document's URL via a "non-HTTP" API, consisting of the new value encoded as UTF-8.
`document.domain`'s getter and setter algorithms call into the algorithm to determine whether or not to throw, as follows:
[`document.write` method](docwrite-method) calls into the algorithm to determine whether or not to throw, as follows:
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.
The `open() method` calls into the algorithm to determine whether or not to throw, as follows:
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 valid enable features, which may be empty.
The permanent message header field registry should be updated with the following registration: [[!RFC3864]]:
TODO