1. Introduction
This section is not normative.
Entry Point Regulation intends to provide defense-in-depth against reflected cross-site scripting and other content injection (XSS), cross-site script inclusion (XSSI), and cross-site request forgery (CSRF) attacks.
These attacks all rely on the fundamentally porous nature of the web: any addressable portion of an application can be requested by any third-party, with arbitrary query parameters and fragment identifiers. The user agent will happily issue such requests with all the authority granted to the user, which can result in a number of problems.
If an author can limit incoming traffic to a strict set of well-audited entry points, web applications can reduce the risk these attacks present, and indeed some authors have taken steps to do so via server-side logic, single page application (SPA) frameworks, (and, soon, via Service Workers). Server-side techniques can be an effective solution, but have a number of drawbacks. Complexity to the side, they are prone to false-positive restrictions in cases where a user’s intent should override the author’s intent (bookmarked links, for instance).
This document defines a browser-enforced mechanism which can be layered on top of an existing application without server-side modifications, providing the attack mitigation authors desire, while allowing user intent to trump brittle filters when possible.
1.1. Goals
The threat model EPR operates under assumes that the user is authenticated to various web applications and origins within a single browser, and that the user browses to web content that may be malicious. Web content can freely make authenticated cross-origin requests, enabling XSS, CSRF, and XSSI attacks. While CSP has shown to be an effective approach to addressing XSS, the protection CSP provides is only as good as the policies web applications are able to put into place. In many cases enforcing optimally secure CSP policies has proven difficult, for example when web content needs to leverage JavaScript libraries requiring eval(). EPR provides a defense-in-depth option for authors to mitigate XSS while also providing a new opportunity to mitigate CSRF and XSSI attacks.
After an author implements EPR for an origin, the following statements ought to hold:
-
Authors should be able to block incoming requests based on the URL being requested. That is, a request for
/
might be allowed, while a request for/api/logout.cgi
might be denied.Modifications might include stripping query and fragment data from the request’s URL, or stripping cookies and other authentication information.
-
Authors should be able to block or modify incoming requests that contain data (e.g. the URL might have query or fragment data, or the request might contain a body) differently from requests that do not contain data.
-
Authors should be able to block or modify incoming requests based on the request’s context; that is, navigations create different attack surfaces than subresource inclusions, and should be treated differently.
-
Requests should be excluded from the above filters if the request originates from a same-origin source. That is, any page on
https://example.com/
may request any resource on that origin, while requests fromhttps://not-example.com/
would be restricted. -
A user agent may choose to exclude other requests from the above filters in order to prioritize a user’s intent. For instance, URLs typed directly into the address bar or bookmarked URLs might skip filters entirely.
1.2. Examples
The developer of a web-based "Internet of Things" administration console would like to have a high degree of assurance that XSS and CSRF attacks will not affect users. If such an attack were to occur it could allow attackers to turn users' home appliances on and off at will, or perform other actions with serious consequences. Because of the pervasive nature of XSS and CSRF vulnerabilities, the developer had been considering creating only monolithic desktop and mobile applications as opposed to utilizing the web platform. While this would allow them to sidestep the security concerns inherent with the web platform, it is clearly not ideal for users. Implementation of CSP seemed to present a solution, however a fully restrictive policy is not possible due to library compatibility requirements.
The developer decides to implement Entry Point Regulation. They create a manifest specifying a default policy to block external requests by default. The developer lists out each entry point path in their manifest. Testing is first performed in report-only mode, and the blocking behavior is only enabled once the developer is comfortable with the behavior of EPR.
2. Key Concepts and Terminology
EPR categorizes requests as follows:
- navigational request if its context frame
type is one of "
top-level
", "auxiliary
", or "nested
". Navigational requests load a resource into a context where markup will be rendered, meaning that they place an origin at risk of both XSS and CSRF attack. - subresource request if it is not a connection request,
and its context frame type is "
none
". Subresource requests cannot execute code directly, so the XSS risk is minimal, but they do present the risk of CSRF and XSSI. - connection request if its context is one
of "
beacon
", "cspreport
", "eventsource
", "fetch
", "ping
", or "xmlhttprequest
". These connection types are distinguished from subresource requests only because of their flexibility (POST
vsGET
, etc) and their typical usage (API endpoints vs static resources). The risks are similar, but authors may wish to set different rules for these kinds of requests than they would for other subresource requests.
In the interest of keeping manifest creation simple, we should consider merging subresource and connection requests into a single category. Navigations are susceptable to XSS, whereas this is not a concern for subresource and connection requests. If there isn’t a similar very specific distinction between attacks that would involve subresource and connection requests than we should merge them.
It could make sense to split out IMAGE SRC, SCRIPT SRC, etc. requests. It should be very easy for a manifest author to tag individual rules in the manifest so that images would be available to IMG tags on a different origin, but not SCRIPT tags. If we can identify a very specific attack scenario where this is useful then it makes sense to do this.
An EPR store is an opaque storage mechanism which offers a user agent the ability to save, retrieve, and modify EPR manifests on a per-origin basis. The implementation is vendor-specific, and the interface provided is not exposed to the web.
The Augmented Backus-Naur Form (ABNF) notation is specified in [RFC5234].
3. Framework
In a nutshell:
- UA requests a resource from
example.com
for the very first time. -
example.com
responds with a document that has anEPR
header, which tells the UA that it should regulate entry points for the origin.As no EPR manifest, and therefore no policy, is available for this request, a default EPR policy will apply as described in §4.2 Default EPR policy.
Somewhere in Fetch after we have the headers, we’ll call out to §4.3 Process response’s EPR header to take whatever actions we need to take here. This means we’ll grab an EPR manifest file, and store it persistently for use in regulating future requests.
-
Subsequent navigations and resource requests from
example.com
will run through §4.1 Process request to determine whether they match the ruleset defined in the EPR manifest we processed above.If they don’t match a ruleset, the user agent will take some action, as described in §3.2.3 Behaviors.
- That’s it!
3.1. The EPR
HTTP Response Header Field
Servers may request the protections outlined in this document by sending an EPR
HTTP response header field along
with a response. This request is represented by the following ABNF:
"EPR:" *WSP "1" *WSP
User agent conformance details upon receipt of such a header are explained in §4.3 Process response’s EPR header.
3.2. Entry Point Manifests
An EPR manifest is a JSON file containing entry point regulation policy data for an origin.
Servers which opt-in to EPR protections via the EPR
header
MUST make a manifest file available via [MANIFEST]. EPR rules are included
in a manifest via the epr_manifest
attribute.
"epr_manifest" attribute inconsistent (?) with "epr" member as described below.
{ ..., "epr": { "reportURL": "https://example.com/reporting-endpoint", "redirectURL": "https://example.com/", "navigationBehavior": "allowStrippedGET", "subresourceBehavior": "allowStrippedGET", "rules": [ { "path": "/", "types": [ "navigational" ], "allowData": false }, { "regex": "^/\\d+$", "types": [ "navigational" ], "allowData": false }, ... { "path": "/image", "types": [ "subresource" ], "allowData": true }, ] } }
It isn’t clear that the EPR manifest ought to be part of an application manifest as defined in [MANIFEST]. We’ve lumped it in there at the moment because it seems worth trying out, but it’s not clear that the concepts (though similar) mesh as well as they need to.
3.2.1. The epr
manifest member
The policy data that makes up the EPR manifest is delivered via an epr
member of an
application manifest [MANIFEST]. This member’s value is an dictionary
adhering to the following IDL:
enum EPRBehavior { "allow", "block", "redirect", "omitCredentials", "allowStrippedGET" }; dictionary EPRPolicy { USVString? reportURL; USVString? redirectURL; EPRBehavior navigationBehavior = "allowStrippedGET"; EPRBehavior subresourceBehavior = "allowStrippedGET"; sequence<EPRRule> rules; };
- reportURL, of type USVString, nullable
-
A URL to which violation reports will be sent. See §4.5 Report request as an entrypoint violation for user
agent conformance requirements.
Note: Authors may use the allow behavior to simulate a "report only" mode that does not actually modify incoming requests but does send reports back to the report URL.
- redirectURL, of type USVString, nullable
- A URL to redirect to when using the redirect behavior.
- navigationBehavior, of type EPRBehavior, defaulting to
"allowStrippedGET"
- If a navigational request doesn’t match
rules
, this property defines the action the user agent will take. Detailed conformance requirements can be found in §4.1 Process request, and a high-level description of the behaviors can be found in §3.2.3 Behaviors. - subresourceBehavior, of type EPRBehavior, defaulting to
"allowStrippedGET"
- If a non-navigational request doesn’t match
rules
, this property defines the action the user agent will take. Detailed conformance requirements can be found in §4.1 Process request, and a high-level description of the behaviors can be found in §3.2.3 Behaviors. - rules, of type sequence<EPRRule>
- The ruleset which should be applied. Details are in §3.2.2 Ruleset.
3.2.2. Ruleset
EPR manifests define a set of rules for a site, governing a user
agent’s fetching behavior for requests made to that site’s origin. Each rule is scoped to a specific subset of an origin’s
URLs via a path prefix or a regular expression. Incoming requests which do not match the ruleset (as defined in §4.4 Does request match rule?) will be dealt
with as defined in navigationBehavior
or subresourceBehavior
, as appropriate.
The following IDL defines rules' syntax:
enum EPRRequestType { "connection", "navigational", "subresource" }; dictionary EPRRule { USVString? path; USVString? regex; sequence<EPRRequestType> types; boolean allowData; };
- path, of type USVString, nullable
- A path prefix defining a rule’s scope. See §4.4 Does request match rule? for user
agent conformance requirements. One
path
orregex
may be specified for a given rule, but not both. - regex, of type USVString, nullable
- A regular expression, defining a rule’s scope. See §4.4 Does request match rule? for user agent conformance requirements. One
path
orregex
may be specified for a given rule, but not both. - types, of type sequence<EPRRequestType>
- A set of request types to which this rule applies: the values MUST be one
or more of "
navigational
" (which encompasses navigational requests), "subresource
" (subresource requests), or "connection
" (connection requests). See §4.4 Does request match rule? for user agent conformance requirements. - allowData, of type boolean
-
If
true
, then matching requests' URLs are allowed to contain non-empty query and fragment properties, and requests' body may be non-null.See §4.1 Process request for user agent conformance requirements.
3.2.3. Behaviors
If a request does not match the ruleset defined in an EPR
manifest’s rules
property, then the user agent looks to
either navigationBehavior
or subresourceBehavior
to determine what action to take.
The following behaviors are defined (and, if none is explicitly specified, then allowStrippedGET is used as a default):
- allow
- Allow the request without modification. This behavior may be used to put the user agent in a "report only" mode, where violations are reported (as described in §4.5 Report request as an entrypoint violation), but requests proceed without modification.
- block
- Cancel the request entirely, returning a network error.
- redirect
- Redirect the request to a specified URL.
- omitCredentials
- Drop cookies and other authentication properties of the request by
setting it’s credentials mode to
"
omit
". - allowStrippedGET
-
Allow
GET
requests, after setting its url’s fragment and query properties tonull
.POST
and other request types will be canceled, returning a network error.
User agent conformance requirements are defined in §4.1 Process request.
3.2.4. Caching
EPR manifest files are cached as per standard policy served in HTTP headers. Manifest files are removed if the user clears their browser cache, as is any persistent indication that EPR has been enabled by the site (as may have been indicated by a HTTP response header). When a manifest file expires from the cache, the user agent should attempt to download the manifest file again when possible. At minimum this should occur on the next request to the EPR-enabled site.
4. Processing Algorithms
4.1. Process request
- Let policy be the policy retrieved from a user agent’s EPR store for request’s URL’s origin.
-
Let rules be the set of rules contained in policy’s
rules
property.Note: rules may be the empty set if no rules are specified. In this case, the behavior specified in the policy’s
navigationBehavior
orsubresourceBehavior
will be applied to all incoming requests. - Let matched be
false
. -
For each rule in rules, if request matches rule:
- Set matched to
true
. - Skip the remaining rules in rules.
- Set matched to
- If matched is true, return without modifying request.
-
Otherwise, let behavior be the value of policy’s
navigationBehavior
if request is a navigational request, andsubresourceBehavior
otherwise. -
Execute the steps associated with the value of behavior in the
list below:
- allow
-
- Return without modifying the request.
- block
-
- Cancel the request, and return a network error.
- redirect
- Do not make the request to the original resource. Redirect the
user agent to the
redirectURL
. - omitCredentials
-
- Set request’s credentials mode property to
omit
. - Set request’s URL’s username to the empty string, and password to
null
.
- Set request’s credentials mode property to
- allowStrippedGET
-
- If request’s method is not
GET
, cancel the request, and return a network error. - Set request’s URL’s fragment and query parameters
to
null
.
- If request’s method is not
- Follow steps in §4.5 Report request as an entrypoint violation.
- Given matched is false, the user agent should initiate a new background manifest download. It is possible that a policy author might make a mistake and deploy a policy that inappropriately blocks access to resources. So initiating a new download when a policy action is applied prevents broken manifests from persisting in the cache. The user agent may choose to implement heuristics so as to avoid excessive manifest download attempts. For example, by never attempting to re-download a manifest more than once an hour.
4.2. Default EPR policy
A default policy MUST be applied when all of the following criteria are met:
- An EPR header has been received by the user agent indicating that the site site has opted-in to EPR.
- No EPR manifest is currently available. (Possibly because it hasn’t been downloaded yet, it failed to parse, etc.
- The request is a navigational request.
- The request was initiated by a cross-origin web site, not by the user’s selection of a bookmark or by the user typing an address into the address bar.
The default EPR policy specifies the allowStrippedGET behavior is applied to requests, preventing requests from containing data that would enable reflected or DOM-based XSS.
Allow data on everything under a specific hardcoded path, in order to facilitate URLs sent in e-mail, etc.?
The intent of the default EPR policy is to mitigate XSS (not CSRF) when no EPR policy is available yet. Even when the user is not authenticated to a site, XSS is problematic because the attack may persist until the user has authenticated. This is not the case with CSRF, and CSRF is not effective until the user has authenticated to a site, at which point it is much more likely that a policy has been downloaded.
Note: The original proposal.
4.3. Process response’s EPR
header
Given a response (response), this algorithm parses its header list to extract an EPR
header field. If such a field is present as EPR: 1, the user agent MUST
fetch and process an EPR manifest from response’s origin unless one or more of the following statements is true:
- response’s request’s context is
manifest
- A manifest for this origin is already cached at the user agent.
- There is already a pending manifest request for the origin.
Once EPR has been enabled for an origin due to the presence of EPR: 1 on a response, EPR is effectively enabled for all resources from this origin, persistently, even if these resources do not specify an EPR header. To disable EPR, an origin must send an EPR: 0 header. The EPR: 0 header is also persistent.
To process response response, execute the following steps:
- If response’s URL is a priori insecure, abort these steps.
-
If response’s header list contains a header named
EPR
, then:- Let manifest URL be the manifest URL provided by [MANIFEST].
- Let request be a request whose method is
GET
, URL is manifest URL, context frame type isnone
, context ismanifest
, and credentials mode isomit
. - Fetch request.
- To process response for the response manifest response:
4.4. Does request match rule?
A request (request) is said to match a rule (rule) if the following algorithm returns Matches
:
- If request is a connection request, and
"
connection
" is not contained in rule’stypes
list, returnDoes Not Match
. - If request is a navigational request, and
"
navigational
" is not contained in rule’stypes
list, returnDoes Not Match
. - If request is a subresource request, and
"
subresource
" is not contained in rule’stypes
list, returnDoes Not Match
. -
If rule has a
path
property whose value is neithernull
norundefined
:- Let rule path be rule’s
path
. - Let exact match be
false
if the final character of rule path is the U+002F SOLIDUS character (/
), andtrue
otherwise. - Let rule path list be the result of splitting rule
path on the U+002F SOLIDUS character (
/
). - If rule path list’s length is greater than url
path list’s length, return
Does Not Match
. -
For each entry in rule path list:
- Percent decode entry.
- Percent decode the first item in url path list.
- If entry is not an ASCII case-insensitive
match for the first item in url path list, return
Does Not Match
- Pop the first item in url path list off the list.
- If exact match is
true
, and url path list is not empty, returnDoes Not Match
- Let rule path be rule’s
-
If rule has a
regex
property whose value is neithernull
norundefined
:- Let rule regex be rule’s
regex
. -
Let url path be the empty string, and for each component in request’s URL’s path:
- Append the U+002F SOLIDUS character (
/
) to url path. - Append component to url path.
- Append the U+002F SOLIDUS character (
-
If url path does not regex match (TODO) rule
regex, return
Does Not Match
.Need to have spec language for this. There’s surely a regex spec somewhere, right? DR: Can we just reference the ECMAScript spec?
- Let rule regex be rule’s
-
If rule’s
allowData
isfalse
, then returnDoes Not Match
if any of the following statements are true: - Return
Matches
.
4.5. Report request as an entrypoint violation
We need to define violation reports. Steal something from CSP.
Proposed format:
{ "epr-report": { "policy-fetch-time": Thu Apr 16 2015 14:23:46 GMT-0700 (PDT) "affected-uri": "http://example.org/page.html", "referrer": "http://evil.example.com/", "type": "navigational", "applied-behavior": "allowStrippedGET", "redirectedTo": "" } }
5. IANA Considerations
5.1. The EPR
HTTP Request Header Field
The permanent message header field registry should be updated with the
following registration [RFC3864]:
- Header field name
- EPR
- Applicable protocol
- http
- Status
- standard
- Author/Change controller
- W3C
- Specification document
- This specification (See §3.1 The EPR HTTP Response Header Field)
6. Acknowledgements
Entry point regulation is an implementation of concepts introduced by Charlie Reis et al. in section 5 of [ISOLATION].