1. Introduction
This section is not normative.
1.1. Examples
iframe
element with a csp
attribute:
<iframe src="https://advertisements-r-us.example.com/ad1.cfm" csp="script-src https://trusted-cdn.example.com/"> </iframe>
This will generate a request to advertisements-r-us.example.com
that has
an Embedding-CSP
header, as follows:
GET / HTTP/1.1 Host: advertisements-r-us.example.com ... Embedding-CSP: script-src https://trusted-cdn.example.com/ ...
The advertisment will only load if it is delivered with a Content Security
Policy which exactly matches the csp
attribute’s value. One way
to do so is to send the requested policy:
HTTP/1.1 200 OK ... Content-Security-Policy: script-src https://trusted-cdn.example.com/
The server might want to futher restrict the document, however. Perhaps it wishes to ensure that plugins will not be loaded. It can do so by sending another policy with additional restrictions:
HTTP/1.1 200 OK ... Content-Security-Policy: script-src https://trusted-cdn.example.com/, object-src 'none'
The ",
" in the Content-Security-Policy
header’s value splits the
string into two serialized policies, each of which is enforced.
2. Framework
2.1. Specifying a Policy Requirement
Browsing contexts have an iframe
security policy attribute, which is null
unless otherwise specified.
iframe
elements have a csp attribute
which specifies the policy that an embedded document must agree to enforce
upon itself.
partial interface HTMLIFrameElement { attribute DOMString csp; };
HTMLIFrameElement
's csp
IDL attribute reflects the value of the element’s csp
content attribute.
When an iframe
element with a csp
attribute has its nested
browsing context created (before the intial about:blank
Document
is
created), and when an iframe
element’s csp
attribute is set
or changed while it has a nested browsing context, the user agent
must set the nested browsing context’s iframe
security policy to the result of executing the parse a serialized policy algorithm on
the csp
attribute’s value.
During the navigate algorithm, perform the following step after the current step 19. At this point, the user agent has fetched a response which it is about to begin parsing, and redirects have been processed:
- If the algorithm in §3.1 Is response blocked by browsing context’s iframe
security policy? returns
Blocked
when executed upon the resource and the browsing context being navigated, abort these steps. The user agent MAY indicate to the user that navigation has been aborted for security reasons.
2.2. The Embedding-CSP
HTTP Request Header
In order to ensure that the embedded resource can decide whether or not it is
willing to adhere to the embedder’s requirements, the policy expressed in an iframe
's csp
attribute is communicated along with some requests via an "Embedding-CSP
" HTTP request
header. The header’s value is represented by the following ABNF [RFC5234]:
Embedding-CSP = serialized-policy
A user agent MUST NOT send more than one HTTP response header field named
"Embedding-CSP
", and any such header MUST NOT contain more than one serialized-policy.
Step ~15 of the navigate algorithm needs to be adjusted to add
an Embedding-CSP
header to a navigational request iff the navigation targets
a nested browsing context, and if the browsing context container is an iframe
element with a csp
attribute. This should be pretty
straightforward once the algorithm is rewritten in terms of Fetch, but is a
bit tricky today.
3. Algorithms
3.1. Is response blocked by browsing context’s iframe
security policy?
Given a response (response) and a browsing context (context), this algorithm returns Allowed
or Blocked
as
appropriate:
-
Let embedding policy be the value of context’s
iframe
security policy. -
Let policy list be the value of response’s policy list.
-
If the §3.2 Is policy list subsumed under subsuming policy? algorithm returns
Subsumed
when executed upon policy list and embedding policy, returnAllowed
. -
Return
Blocked
.
3.2. Is policy list subsumed under subsuming policy?
Given a list of policy objects (policy list), this algorithm
returns Subsumed
if that list enforces a policy which is an exact
match for a given policy object (subsuming policy). It
returns Not Subsumed
otherwise.
Note: I have delusions of someday defining a real subsumption algorithm
which would verify that the policy default-src 'none'; script-src https://example.com
is subsumbed under default-src *.example.com
(as
there is no case in which the latter will block a request that the former
would allow). That calculation turns out to be hard, so the current algorithm
takes the significantly simpler approach of requiring an exact match.
Note: This is not an efficient algorithm. Implementers are encouraged to implement something a little smarter and faster, with the same behavior.
-
If subsuming policy is
null
, returnSubsumed
. -
For each policy in policy list:
-
If policy’s disposition is not
Enforce
, set skip to the next policy. -
If policy’s directive set is not the same size as subsuming policy’s directive set, skip to the next policy.
-
For each directive in policy’s directive set:
-
Let subsuming directive be the directive in subsuming policy’s directive set whose name matches directive’s name, or
null
if no such directive is present. -
If subsuming directive is
null
, skip to the next policy. -
If subsuming directive’s value list is not the same size as directive’s value list, skip to the next policy.
-
For each token in directive’s value:
-
If token is not present in subsuming directive’s value, skip to the next policy.
-
-
-
Return
Subsumed
.
-
-
Return
Not Subsumed
.