diff --git a/index.bs b/index.bs index da776d4..667a889 100644 --- a/index.bs +++ b/index.bs @@ -28,9 +28,28 @@ spec: ABNF; urlPrefix: https://tools.ietf.org/html/rfc5234 type: dfn text: VCHAR; url: appendix-B.1 text: WSP; url: appendix-B.1 + text: OWS; url: appendix-B.1 type: grammar text: VCHAR; url: appendix-B.1 text: WSP; url: appendix-B.1 + text: OWS; url: appendix-B.1 + +spec: HTTP; urlPrefix: https://tools.ietf.org/html/rfc7230 + type: dfn + text: token; url: #section-3.2.6 + type: grammar + text: token; url: #section-3.2.6 + +spec: CSP; urlPrefix: https://w3c.github.io/webappsec-csp/ + type: dfn + text: Content Security Policy; urlPrefix: # + text: policy; url: policy + text: directive; url: directives + text: value; for: directive; url: directive-value + text: pre-request check; url: directive-pre-request-check + text: create a violation object for global; url: create-violation-for-global + text: report violation; url: report-violation + text: disposition; for: policy spec: RFC7234; urlPrefix: https://tools.ietf.org/html/rfc7234 type: dfn @@ -203,8 +222,6 @@ spec:csp3; type:grammar; text:base64-value Content Security Policy defines the <a grammar>`base64-value`</a> and <a grammar>`hash-algorithm`</a> rules. [[!CSP]] - </section> - <!-- ####################################################################### --> # Framework # {#framework} @@ -322,7 +339,103 @@ spec:csp3; type:grammar; text:base64-value supported by this specification. - ## Response verification algorithms ## {#verification-algorithms} + ## Request verification algorithms ## {#request-verification-algorithms} + + ### Opting-in ### {#opt-in-integrity-required} + + Authors may opt a {{Document}} to require SRI metadata be present for + some resource types via a <dfn export>integrity-required</dfn> <a>Content + Security Policy</a> directive defined by the following ABNF grammar: + + <pre dfn-type="grammar" link-type="grammar"> + directive-name = "integrity-required" + directive-value = <a grammar>token</a> *( <a>OWS</a> <a>token</a> ) + </pre> + + The following list contains the set of <dfn noexport>known tokens</dfn>: + + * `script` requires SRI for scripts + + + ### Parsing `integrity-required` ### {#parse-integrity-required} + + Given a string (|token list|), this algorithm returns a list of resource + types which will require integrity checks: + + 1. Let |protected resource types| be the empty <a for=/>set</a>. + + 2. For each |token| in the result of <a lt="split a string on ascii whitespace"> + splitting |token list| on spaces</a>, if token matches the grammar + for <a>integrity-required</a> and is a <a>ASCII case-insensitive match</a> + for any of the <a>known token</a>s, add |token| to |protected resource types|. + Otherwise, ignore the token. + + 3. Return the set of |protected resource types|. + + ### Apply |algorithm| to |request| ### {#apply-algorithm-to-request} + + This directive’s <a>pre-request check</a> is as follows: + + Given a <a for="/">request</a> (|request|) and a <a>policy</a> (<var ignore>policy</var>): + + 1. If |request|'s <a for=request>url</a>'s <a for=url>scheme</a> <a>is local</a>, + return "Allowed". + + 2. Let |protected resource types| be the result of executing + [[#parse-integrity-required]] on this <a>directive</a>'s <a for="directive">value</a>. + + 3. Let |protected| be a <a>boolean</a>, initially set to false. + + 4. <a for=set>For each</a> |token| of |protected resource types|, + if |request|'s <a for=request>destination</a> is an <a>ASCII case-insensitive match</a> for |token|, + set |protected| to true. + + Note: Matching tokens to the request's destination means that worker and worklets will not be covered by `integrity-required script`, + and will not require integrity checks when it's defined. + Once we have a way to define integrity metadata for workers or worklets + (e.g. [HTML#10858](https://github.com/whatwg/html/pull/10858)), we would be able to add a separate token for them. + + + 5. If |protected| is false, + return "Allowed". + + 6. Let |parsedMetadata| be the result of <a href="#parse-metadata">parsing</a> |request|'s + <a>integrity metadata</a>. + + 7. If |request|'s <a for=request>mode</a> is not "no-cors" and + |parsedMetadata| is not the empty <a for=/>set</a>, + return "Allowed". + + Note: This logic means that request with matched <a for=request>destination</a> and missing + <a>integrity metadata</a> will be blocked even if it is not currently possible to set its + <a>integrity metadata</a>. + Such requests are originated by, for example, <code>importScripts()</code>, + or `script` elements without crossorigin content attribute. + + 8. Return "Blocked". + + <div class="example"> + A page with the following Content Security Policy: + + <pre> + Content-Security-Policy: <a>integrity-required</a> script + </pre> + + is equivalent to Content Security Policy delivered through `<meta>` + element: + + <pre> + <meta http-equiv="Content-Security-Policy" + content="<a>integrity-required</a> script"> + </pre> + + + and requires <a>integrity metadata</a> be present in `script` + elements that contain `src` attribute. + </div> + + + ## Response verification algorithms ## {#response-verification-algorithms} ### Apply |algorithm| to |bytes| ### {#apply-algorithm-to-response} @@ -547,6 +660,17 @@ spec:csp3; type:grammar; text:base64-value to load the document. A successful load would confirm that the attacker has correctly guessed the username. + + <section> + <h2 id="iana-considerations">IANA Considerations</h2> + + The Content Security Policy Directive registry should be updated with the + following directives and references [[!RFC7762]]: + + : <a>`integrity-required`</a> + :: This document (see [[#opt-in-integrity-required]]) + </section> + <!-- ####################################################################### --> # Acknowledgements # {#acknowledgements}