Abstract

This document defines a mechanism by which web developers can control the
resources which a particular page can fetch or execute, as well as a number
of security-relevant policy decisions.

Status of this document

This section describes the status of this document at the time of
its publication. Other documents may supersede this document. A list of
current W3C publications and the latest revision of this technical report
can be found in the W3C technical reports
index at https://www.w3.org/TR/.

The (archived) public mailing list public-webappsec@w3.org (see instructions)
is preferred for discussion of this specification.
When sending e-mail,
please put the text “CSP3” in the subject,
preferably like this:
“[CSP3] …summary of comment…”

Publication as a Working Draft does not imply endorsement by the W3C
Membership. This is a draft document and may be updated, replaced or
obsoleted by other documents at any time. It is inappropriate to cite this
document as other than work in progress.

“At-risk” is a W3C Process term-of-art, and does not necessarily imply that the feature is in danger of being dropped or delayed. It means that the WG believes the feature may have difficulty being interoperably implemented in a timely manner, and marking it as such allows the WG to drop the feature if necessary when transitioning to the Proposed Rec stage, without having to publish a new Candidate Rec without the feature first.

1. Introduction

This section is not normative.

This document defines Content Security Policy (CSP), a tool
which developers can use to lock down their applications in various ways,
mitigating the risk of content injection vulnerabilities such as cross-site scripting, and
reducing the privilege with which their applications execute.

CSP is not intended as a first line of defense against content injection
vulnerabilities. Instead, CSP is best used as defense-in-depth. It reduces
the harm that a malicious injection can cause, but it is not a replacement for
careful input validation and output encoding.

This document is an iteration on Content Security Policy Level 2, with the
goal of more clearly explaining the interactions between CSP, HTML, and Fetch
on the one hand, and providing clear hooks for modular extensibility on the
other. Ideally, this will form a stable core upon which we can build new
functionality.

1.1. Examples

1.1.1. Control Execution

MegaCorp Inc’s developers want to protect themselves against cross-site
scripting attacks. They can mitigate the risk of script injection by
ensuring that their trusted CDN is the only origin from which script can
load and execute. Moreover, they wish to ensure that no plugins can
execute in their pages' contexts. The following policy has that effect:

Mitigate the risk of attacks which require a resource to be embedded
in a malicious context (the "Pixel Perfect" attack described in [TIMING], for example) by giving developers granular control over the
origins which can embed a given resource.

Provide a policy framework which allows developers to reduce the privilege
of their applications.

Provide a reporting mechanism which allows developers to detect flaws
being exploited in the wild.

1.3. Changes from Level 2

This document describes an evolution of the Content Security Policy Level 2
specification [CSP2]. The following is a high-level overview of the changes:

The specification has been rewritten from the ground up in terms of the [FETCH] specification, which should make it simpler to integrate CSP’s
requirements and restrictions with other specifications (and with
Service Workers in particular).

The frame-src directive, which was deprecated in CSP Level
2, has been undeprecated, and a worker-src directive added. Both defer
to child-src if not present (which defers to default-src in turn).

The URL matching algorithm now treats insecure schemes and ports as
matching their secure variants. That is, the source expression http://example.com:80 will match both http://example.com:80 and https://example.com:443.

Likewise, 'self' now matches https: and wss: variants of the page’s
origin, even on pages whose scheme is http.

Violation reports generated from inline script or style will now report
"inline" as the blocked resource. Likewise, blocked eval() execution
will report "eval" as the blocked resource.

The manifest-src directive has been added.

The report-uri directive is deprecated in favor of the new report-to directive, which relies on [OOB-REPORTING] as infrastructure.

2.2.1. Source Lists

Many directives' values consist of source lists: sets
of tokens which identify content that can be fetched and potentially embedded
or executed. These tokens represent one of the following types of source
expression:

Keywords such as 'none' and 'self' (which match nothing and the current
URL’s origin, respectively)

Serialized URLs such as https://example.com/path/to/file.js (which matches a specific file) or https://example.com/ (which matches everything on that origin)

Schemes such as https: (which matches any resource having
the specified scheme)

Hosts such as example.com (which matches any resource on
the host, regardless of scheme) or *.example.com (which
matches any resource on the host or any of its subdomains (and any of
its subdomains' subdomains, and so on))

Nonces such as 'nonce-qwertyu12345' (which can match specific
elements on a page)

Digests such as 'sha256-abcd...' (which can match specific
elements on a page)

A serialized source list is an ASCII string, consisting of a
space-delimited series of source expressions, adhering to the
following ABNF grammar [RFC5234]:

The host-char production intentionally contains only ASCII
characters; internationalized domain names cannot be entered directly as part
of a serialized CSP, but instead MUST be Punycode-encoded [RFC3492]. For example, the domain üüüüüü.de MUST be represented as xn--tdaaaaaa.de.

If the user agent is currently executing script, and can extract a source
file’s URL, line number, and column number from the global, set violation’s source file, line
number, and column number accordingly.

Is this kind of thing specified anywhere? I didn’t see anything
that looked useful in [ECMA262].

The Content-Security-Policy-Report-Only HTTP response
header field allows web developers to experiment with policies by monitoring
(but not enforcing) their effects. The header’s value is represented by the
following ABNF [RFC5234]:

This header field allows developers to piece together their security policy in
an iterative fashion, deploying a report-only policy based on their best
estimate of how their site behaves, watching for violation reports, and then
moving to an enforced policy once they’ve gained confidence in that behavior.

Authors are strongly encouraged to place meta elements as early
in the document as possible, because policies in meta elements are not
applied to content which precedes them. In particular, note that resources
fetched or prefetched using the Link HTTP response header
field, and resources fetched or prefetched using link and script elements which precede a meta-delivered policy will not be blocked.

Note: A policy specified via a meta element will be enforced along with
any other policies active for the protected resource, regardless
of where they’re specified. The general impact of enforcing multiple
policies is described in §8.1 The effect of multiple policies.

Note: Modifications to the content attribute of a meta element
after the element has been parsed will be ignored.

4. Integrations

This section is non-normative.

This document defines a set of algorithms which are used in other
specifications in order to implement the functionality. These
integrations are outlined here for clarity, but those external
documents are the normative references which ought to be consulted for
detailed information.

4.1. Integration with Fetch

A number of directives control resource loading in one way or
another. This specification provides algorithms which allow Fetch to make
decisions about whether or not a particular request should be blocked
or allowed, and about whether a particular response should be replaced
with a network error.

A policy is generally enforced upon a global object, but the
user agent needs to parse any policy
delivered via an HTTP response header field before any global object is created in order to handle directives that require knowledge of a response’s details. To that end:

Note: These two calls should ensure that a response’s CSP list is set, regardless of how the response is created. If we hit the network (via HTTP-network
fetch, then we parse the policy before we handle the Set-Cookie header. If we get a response from a Service Worker (via HTTP fetch,
we’ll process its CSP list before handing the
response back to our caller.

Given an Element (element), a string (type), and a string (source)
this algorithm returns "Allowed" if the element is allowed to have inline
definition of a particular type of behavior (script execution, style
application, event handlers, etc.), and "Blocked" otherwise:

4.2.4. Should navigation request of type from source in target be blocked
by Content Security Policy?

Given a request (navigation request), a string (type, either
"form-submission" or "other"), and two browsing contexts (source and target), this algorithm return "Blocked" if the active policy blocks
the navigation, and "Allowed" otherwise:

4.2.5. Should navigation response to navigation request of type from source in target be blocked by Content Security Policy?

Given a request (navigation request),, a string (type, either
"form-submission" or "other"), a responsenavigation
response, and two browsing contexts (source and target), this algorithm
returns "Blocked" if the active policy blocks the navigation, and "Allowed"
otherwise:

4.3. Integration with ECMAScript

ECMAScript defines a HostEnsureCanCompileStrings() abstract operation
which allows the host environment to block the compilation of strings into
ECMAScript code. This document defines an implementation of that abstract
operation thich examines the relevant CSP list to determine whether such compilation ought to be blocked.

5.2. Obtain the deprecated serialization of violation

Given a violation (violation), this algorithm returns a JSON text
string representation of the violation, suitable for submission to a reporting
endpoint associated with the deprecated report-uri directive.

Let object be a new JavaScript object with properties initialized as
follows:

"document-uri"

The result of executing the URL serializer on violation’s url, with the exclude fragment flag set.

In either case, developers SHOULD NOT include either 'unsafe-inline', or data: as valid
sources in their policies. Both enable XSS attacks by allowing code to be
included directly in the document itself; they are best avoided completely.

6.1. Fetch Directives

Fetch directives control the locations from which certain resourc
types may be loaded. For instance, script-src allows developers to
whitelist trusted sources of script to execute on a page, while font-src controls the sources of web fonts.

6.1.1. child-src

The child-src directive governs the creation of nested browsing
contexts (e.g. iframe and frame navigations) and Worker execution
contexts. The syntax for the directive’s name and value is described by the
following ABNF:

This directive controls requests which transmit or receive data from
other origins. This includes APIs like fetch(), [XHR], [EVENTSOURCE], [BEACON], and a's ping. This directive also controls
WebSocket [WEBSOCKETS] connections, though those aren’t technically part
of Fetch.

JavaScript offers a few mechanisms that directly connect to an external
server to send or receive information. EventSource maintains an open
HTTP connection to a server in order to receive push notifications, WebSockets open a bidirectional communication channel between your
browser and a server, and XMLHttpRequest makes arbitrary HTTP requests
on your behalf. These are powerful APIs that enable useful functionality,
but also provide tempting avenues for data exfiltration.

The connect-src directive allows you to ensure that these and similar
sorts of connections are only opened to origins you trust. Sending a
policy that defines a list of source expressions for this directive is
straightforward. For example, to limit connections to only https://example.com, send the following header:

Given this behavior, one good way to build a policy for a site would be to
begin with a default-src of 'none', and to build up a policy from there
which allowed only those resource types which are necessary for the
particular page the policy will apply to.

If plugin content is loaded without an associated URL (perhaps an object element lacks a data attribute, but loads some default plugin based
on the specified type), it MUST be blocked if object-src's value is 'none', but will otherwise be allowed.

Note: The object-src directive acts upon any request made on behalf of
an object, embed, or applet element. This includes requests
which would populate the nested browsing context generated by the
former two (also including navigations). This is true even when the data is
semantically equivalent to content which would otherwise be restricted by
another directive, such as an object element with a text/html MIME
type.

6.1.10. script-src

The script-src directive restricts the locations from which scripts
may be executed. This includes not only URLs loaded directly into script elements, but also things like inline script blocks and XSLT stylesheets [XSLT] which can trigger script execution. The syntax for the directive’s
name and value is described by the following ABNF:

Note: Here, we verify only that the request contains a set of integrity metadata which is a subset of the hash-sourcesource expressions whitelisted by
this directive. We rely on the browser’s enforcement of Subresource
Integrity [SRI] to block non-matching resources upon response.

Do something interesting to the execution context in order to lock down
interesting CSSOM algorithms. I don’t think CSSOM gives us any hooks here, so
let’s work with them to put something reasonable together.

6.1.12. worker-src

The worker-src directive restricts the URLs which may be loaded as
a Worker, SharedWorker, or ServiceWorker. The syntax for the
directive’s name and value is described by the following ABNF:

6.2.2. plugin-types

The plugin-types directive restricts the set of plugins that
can be embedded into a document by limiting the types of resources which can
be loaded. The directive’s syntax is described by the following ABNF grammar:

6.2.3. sandbox

The sandbox directive specifies an HTML sandbox policy which the
user agent will apply to a resource, just as though it had been included in
an iframe with a sandbox property.

The directive’s syntax is described by the following ABNF grammar, with
the additional requirement that each token value MUST be one of the
keywords defined by HTML specification as allowed values for the iframesandbox attribute [HTML].

Not sure this is the right model. We need to ensure that we take care
of the inverse as
well, and there might be a cleverer syntax that could encompass both a
document’s opener, and a document’s openees. disown-openee is weird.
Maybe disown 'opener' 'openee'? Do we need origin restrictions on either/both?

6.3.1.1. form-action Pre-Navigation Check

Given a request (request), a string (type, "form-submission or
"other") and two browsing contexts (source and target), this
algorithm returns "Blocked" if one or more of the ancestors of target violate the frame-ancestors directive delivered with the response, and
"Allowed" otherwise. This constitutes the form-action' directive’s pre-navigation check:

Assert: source and target are unused in this algorithm, as form-action is concerned only with details of the outgoing request.

6.3.2. frame-ancestors

The frame-ancestors directive restricts the URLs which can
embed the resource using frame, iframe, object, embed, or applet element. Resources can use this directive to avoid many UI
Redressing [UISECURITY] attacks, by avoiding the risk of being embedded into
potentially hostile contexts.

The frame-ancestors directive MUST be ignored when contained in a policy
declared via a meta element.

Note: The frame-ancestors directive’s syntax is similar to a source
list, but frame-ancestors will not fall back to the default-src directive’s value if one is specified. That is, a policy that declares default-src 'none' will still allow the resource to be embedded by anyone.

6.3.2.1. frame-ancestors Navigation Response Check

Given a request (request), a response (navigation response)
and two browsing contexts (source and target), this algorithm
returns "Blocked" if one or more of the ancestors of target violate the frame-ancestors directive delivered with the response, and "Allowed"
otherwise. This constitutes the frame-ancestors' directive’s navigation
response check:

Assert: request, navigation response, and source are unused in
this algorithm, as frame-ancestors is concerned only with target’s
ancestors.

6.4.1. report-uri

Note: The report-uri directive is deprecated. Please use the report-to directive instead. If the latter directive is present,
this directive will be ignored. To ensure backwards compatibility, we
suggest specifying both, like this:

6.5. Directives Defined in Other Documents

This document defines a core set of directives, and sets up a framework for
modular extension by other specifications. At the time this document was
produced, the following stable documents extend CSP:

6.6.1.5. Does url match source list in origin with redirect count?

Given a URL (url), a source list (source list), an origin (origin), and a number (redirect count), this
algorithm returns "Matches" if the URL matches one or more source
expressions in source list, or "Does Not Match" otherwise:

Assert: source list is not null.

If source list is an empty list, return "Does Not Match".

If source list contains a single item which is an ASCII
case-insensitive match for the string "'none'", return "Does Not Match".

Note: An empty source list (that is, a directive without a value: script-src,
as opposed to script-src host1) is equivalent to a source list containing 'none',
and will not match any URL.

Note: This logic means that in order to allow resource from a non-network scheme,
it has to be either explicitly whitelisted: default-src * data: custom-scheme-1: custom-scheme-2:,
or the protected resource must be loaded from the same scheme.

Note: This logic effectively means that script-src http: is
equivalent to script-src http: https:, and script-src http://example.com/ is equivalent to script-src http://example.com https://example.com. As well as WebSocket
schemes are equivalent to corresponding HTTP schemes. In short,
we always allow a secure upgrade from an explicitly insecure expression.

Note: A future version of this specification may allow literal IPv6
and IPv4 addresses, depending on usage and demand. Given the weak
security properties of IP addresses in relation to named hosts,
however, authors are encouraged to prefer the latter whenever
possible.

Note: Like the scheme-part logic above, the "'self'"
matching algorithm allows upgrades to secure schemes when it is safe to do
so. We limit these upgrades to endpoints running on the default port for a
particular scheme or a port that matches the origin of the protected
resource, as this seems sufficient to deal with upgrades that can be
reasonably expected to succeed.

Return "Does Not Match".

6.6.1.7. Get the effective directive for request

Each fetch directive controls a specific type of request. Given
a request (request), the following algorithm returns either null or the name of the request’s effective directive:

6.6.2. Element Matching Algorithms

6.6.2.1. Is element nonceable?

Given an Element (element), this algorithm returns "Nonceable" if
a nonce-source expression can match the element (as discussed
in §7.2 Nonce Stealing), and "Not Nonceable" if such expressions
should not be applied.

If element does not have an attribute named "nonce", return "Not Nonceable".

If attribute’s name is an ASCII case-insensitive match for
the string "<script" or the string "<style", return "Not Nonceable".

If attribute’s value contains an ASCII case-insensitive match
for the string "<script" or the string "<style", return "Not Nonceable".

Return "Nonceable".

This processing is meant to mitigate the risk
of dangling markup attacks that steal the nonce from an existing element
in order to load injected script. It is fairly expensive, however, as it
requires that we walk through all attributes and their values in order to
determine whether the script should execute. Here, we try to minimize the
impact by doing this check only for script elements when a nonce is
present, but we should probably consider this algorithm as "at risk" until
we know its impact. <https://github.com/w3c/webappsec-csp/issues/98>

6.6.2.2. Does element match source list for type and source?

Given an Element (element), a source list (list), a string
(type), and a string (source), this algorithm returns "Matches" or
"Does Not Match".

7. Security and Privacy Considerations

7.1. Nonce Reuse

Nonces override the other restrictions present in the directive in which
they’re delivered. It is critical, then, that they remain unguessable, as
bypassing a resource’s policy is otherwise trivial.

If a server delivers a nonce-source expression as part of a policy, the server MUST generate a unique value each time it
transmits a policy. The generated value SHOULD be at least 128 bits long
(before encoding), and SHOULD be generated via a cryptographically secure
random number generator in order to ensure that the value is difficult for
an attacker to predict.

Note: Using a nonce to whitelist inline script or style is less secure than
not using a nonce, as nonces override the restrictions in the directive in
which they are present. An attacker who can gain access to the nonce can
execute whatever script they like, whenever they like. That said, nonces
provide a substantial improvement over 'unsafe-inline' when
layering a content security policy on top of old code. When considering 'unsafe-inline', authors are encouraged to consider nonces
(or hashes) instead.

7.2. Nonce Stealing

Dangling markup attacks such as those discussed in [FILEDESCRIPTOR-2015] can be used to repurpose a page’s legitimate nonces for injections. For
example, given an injection point before a script element:

It will then parse that code, ending up with a script element with a src attribute pointing to a malicious payload, an attribute named </p>,
an attribute named <script, a nonce attribute, and a second src attribute which is helpfully discarded as duplicate by the parser.
The §6.6.2.1 Is element nonceable? algorithm attempts to mitigate this specific
attack by walking through script element attributes, looking for the
string "<script" or "<style" in their names or values.

7.3. CSS Parsing

The style-src directive restricts the locations from which the
protected resource can load styles. However, if the user agent uses a lax CSS
parsing algorithm, an attacker might be able to trick the user agent into
accepting malicious "stylesheets" hosted by an otherwise trustworthy origin.
These attacks are similar to the CSS cross-origin data leakage attack
described by Chris Evans in 2009 [CSS-ABUSE]. User agents SHOULD defend
against both attacks using the same mechanism: stricter CSS parsing rules for
style sheets with improper MIME types.

7.4. Violation Reports

The violation reporting mechanism in this document has been designed to
mitigate the risk that a malicious web site could use violation reports to
probe the behavior of other servers. For example, consider a malicious web
site that whitelists https://example.com as a source of images. If the
malicious site attempts to load https://example.com/login as an image, and
the example.com server redirects to an identity provider (e.g. identityprovider.example.net), CSP will block the request. If violation
reports contained the full blocked URL, the violation report might contain
sensitive information contained in the redirected URL, such as session
identifiers or purported identities. For this reason, the user agent includes
only the URL of the original request, not the redirect target.

8. Authoring Considerations

8.1. The effect of multiple policies

This section is not normative. The above sections note that when multiple policies are present, each must be
enforced or reported, according to its type. An example will help clarify how
that ought to work in practice. The behavior of an XMLHttpRequest might seem unclear given a site that, for whatever reason, delivered the
following HTTP headers:

Is a connection to example.com allowed or not? The short answer is that the
connection is not allowed. Enforcing both policies means that a potential
connection would have to pass through both unscathed. Even though the second
policy would allow this connection, the first policy contains connect-src 'none', so its enforcement blocks the connection. The
impact is that adding additional policies to the list of policies to enforce
can only further restrict the capabilities of the protected resource.
To demonstrate that further, consider a script tag on this page. The first
policy would lock scripts down to 'self', http://example.com and http://example.net via the default-src directive. The second, however,
would only allow script from http://example.com/. Script will only load if
it meets both policy’s criteria: in this case, the only origin that can match
is http://example.com, as both policies allow it.

8.2. Usage of "'strict-dynamic'"

Whitelists are tough to get right, especially on sprawling origins like CDNs.
The solutions
to Cure53’s H5SC Minichallenge 3: "Sh*t, it’s CSP!"[H5SC3] are good
examples of the kinds of bypasses which whitelists can enable, and though CSP
is capable of mitigating these bypasses via extensive whitelists, those end
up being brittle, awkward, and difficult to implement and maintain.
The "'strict-dynamic'" source expression aims to make Content
Security Policy simpler to deploy for existing applications who have a high
degree of confidence in the scripts they load directly, but low confidence in
their ability to provide a reasonably secure whitelist.
If present in a script-src or default-src directive, it has
two main effects:
1. host-source and scheme-source expressions, as well as the "'unsafe-inline'"
and "'self'keyword-sources will be
ignored when loading script. hash-source and nonce-source expressions
will be honored.
2. Script requests which are triggered by non-"parser-inserted"script elements are allowed.
The first change allows you to deploy "'strict-dynamic' in a
backwards compatible way, without requiring user-agent sniffing: the policy 'unsafe-inline' https: 'nonce-abcdefg' 'strict-dynamic' will act like 'unsafe-inline' https: in browsers that support CSP1, https: 'nonce-abcdefg' in browsers that support CSP2, and 'nonce-abcdefg' 'strict-dynamic' in browsers that support CSP3.
The second allows scripts which are given access to the page via nonces or
hashes to bring in their dependencies without adding them explicitly to the
page’s policy.

8.3. Usage of "'unsafe-hashed-attributes'"

This section is not normative. Legacy websites and websites with legacy dependencies might find it difficult
to entirely externalize event handlers. These sites could enable such handlers
by whitelisting 'unsafe-inline', but that’s a big hammer with a lot of
associated risk (and cannot be used in conjunction with nonces or hashes).
The "'unsafe-hashed-attributes'" source expression aims to make
CSP deployment simpler and safer in these situations by allowing developers
to whitelist specific handlers via hashes.

MegaCorp, Inc. can’t quite get rid of the following HTML on anything
resembling a reasonable schedule:

<button id="action" onclick="doSubmit()">

Rather than whitelisting "'unsafe-inline'", they decide to use
"'unsafe-hashed-attributes'" along with a hash source expression, as follows:

8.4. Whitelisting external JavaScript with hashes

This section is not normative. In [CSP2], hash source expressions could only whitelist inlined
script, but now that Subresource Integrity is widely deployed, we can expand
the scope to enable externalized JavaScript as well.
If multiple sets of integrity metadata are specified for a script, the
request will match a policy’s hash-sources if and only if each item in a script's integrity metadata matches the policy.

MegaCorp, Inc. wishes to whitelist two specific scripts on a page in a way
that ensures that the content matches their expectations. They do so by
setting the following policy:

Content-Security-Policy: script-src 'sha256-abc123' 'sha512-321cba'

In the presence of that policy, the following script elements would be
whitelisted because they contain only integrity metadata that matches the
policy:

9. Implementation Considerations

9.1. Vendor-specific Extensions and Addons

Policy enforced on a resource SHOULD NOT interfere with the operation
of user-agent features like addons, extensions, or bookmarklets. These kinds
of features generally advance the user’s priority over page authors, as
espoused in [HTML-DESIGN].
Moreover, applying CSP to these kinds of features produces a substantial
amount of noise in violation reports, significantly reducing their value to
developers.
Chrome, for example, excludes the chrome-extension: scheme from CSP checks,
and does some work to ensure that extension-driven injections are allowed,
regardless of a page’s policy.

11. Acknowledgements

Lots of people are awesome. For instance:
* Mario and all of Cure53.
* Artur Janc, Michele Spagnuolo, Lukas Weichselbaum, Jochen Eisinger, and the
rest of Google’s CSP Cabal.

Conformance

Document conventions

Conformance requirements are expressed with a combination of
descriptive assertions and RFC 2119 terminology. The key words “MUST”,
“MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”,
“RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this
document are to be interpreted as described in RFC 2119.
However, for readability, these words do not appear in all uppercase
letters in this specification.

All of the text of this specification is normative except sections
explicitly marked as non-normative, examples, and notes. [RFC2119]

Examples in this specification are introduced with the words “for example”
or are set apart from the normative text with class="example",
like this:

This is an example of an informative example.

Informative notes begin with the word “Note” and are set apart from the
normative text with class="note", like this:

Note, this is an informative note.

Conformant Algorithms

Requirements phrased in the imperative as part of algorithms (such as
"strip any leading space characters" or "return false and abort these
steps") are to be interpreted with the meaning of the key word ("must",
"should", "may", etc) used in introducing the algorithm.

Conformance requirements phrased as algorithms or specific steps can be
implemented in any manner, so long as the end result is equivalent. In
particular, the algorithms defined in this specification are intended to
be easy to understand and are not intended to be performant. Implementers
are encouraged to optimize.

Do something interesting to the execution context in order to lock down
interesting CSSOM algorithms. I don’t think CSSOM gives us any hooks here, so
let’s work with them to put something reasonable together. ↵

Not sure this is the right model. We need to ensure that we take care
of the inverse as
well, and there might be a cleverer syntax that could encompass both a
document’s opener, and a document’s openees. disown-openee is weird.
Maybe disown 'opener' 'openee'? Do we need origin restrictions on either/both? ↵

This processing is meant to mitigate the risk
of dangling markup attacks that steal the nonce from an existing element
in order to load injected script. It is fairly expensive, however, as it
requires that we walk through all attributes and their values in order to
determine whether the script should execute. Here, we try to minimize the
impact by doing this check only for script elements when a nonce is
present, but we should probably consider this algorithm as "at risk" until
we know its impact. <https://github.com/w3c/webappsec-csp/issues/98> ↵