Skip to content

Add some information for authors about the intent of the spec #103

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 93 additions & 11 deletions index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ spec: SHA2; urlPrefix: http://csrc.nist.gov/publications/fips/fips180-4/fips-180
of the representation of the resource the author expects to load. For instance,
an author may wish to load some framework from a shared server rather than hosting it
on their own origin. Specifying that the <em>expected</em> SHA-384 hash of
`https://example.com/example-framework.js`
`https://example.com/v1.0/example-framework.js`
is `Li9vy3DqF8tnTXuiaAJuML3ky+er10rcgNR/VqsVpcw+ThHmYcwiB1pbOxEbzJr7` means
that the user agent can verify that the data it loads from that URL matches
that expected hash before executing the JavaScript it contains. This
Expand All @@ -129,12 +129,17 @@ spec: SHA2; urlPrefix: http://csrc.nist.gov/publications/fips/fips180-4/fips-180

<div class="example">
<pre>
&lt;script src="https://example.com/example-framework.js"
&lt;script src="https://example.com/v1.0/example-framework.js"
integrity="sha384-Li9vy3DqF8tnTXuiaAJuML3ky+er10rcgNR/VqsVpcw+ThHmYcwiB1pbOxEbzJr7"
crossorigin="anonymous"&gt;&lt;/script&gt;
</pre>
</div>

In the event that the expected hash does not match the hash of the downloaded
resource, indicating a potential compromise of the server, the user agent will
refuse to parse or execute the resource, and will fire an error to alert
developers to the failure.

Scripts, of course, are not the only response type which would benefit
from integrity validation. The scheme specified here also applies to `link`
and future versions of this specification are likely to expand this coverage.
Expand Down Expand Up @@ -164,7 +169,7 @@ spec: SHA2; urlPrefix: http://csrc.nist.gov/publications/fips/fips180-4/fips-180

<div class="example">
<pre>
&lt;link rel="stylesheet" href="https://site53.example.net/style.css"
&lt;link rel="stylesheet" href="https://site53.example.net/v1.0/style.css"
integrity="sha384-+/M6kredJcxdsqkczBUjMLvqyHb1K/JThDXWsBVxMEeZHEaMKEOEct339VItX1zB"
crossorigin="anonymous"&gt;
</pre>
Expand Down Expand Up @@ -322,7 +327,7 @@ spec: SHA2; urlPrefix: http://csrc.nist.gov/publications/fips/fips180-4/fips-180
To allow authors to switch to stronger hash functions without being held back by older
user agents, validation using unsupported hash functions acts like no integrity value
was provided (see the [[#does-response-match-metadatalist]] algorithm below).
Authors are encouraged to use strong hash functions, and to begin migrating to
Authors are encouraged to use strong hash functions, and to begin migrating to
stronger hash functions as they become available.

### Priority ### {#priority}
Expand Down Expand Up @@ -411,7 +416,7 @@ spec: SHA2; urlPrefix: http://csrc.nist.gov/publications/fips/fips180-4/fips-180

<div class="example">
<pre>
&lt;script src="https://example.com/example-framework.js"
&lt;script src="https://example.com/v1.0/example-framework.js"
integrity="sha384-Li9vy3DqF8tnTXuiaAJuML3ky+er10rcgNR/VqsVpcw+ThHmYcwiB1pbOxEbzJr7
sha384-+/M6kredJcxdsqkczBUjMLvqyHb1K/JThDXWsBVxMEeZHEaMKEOEct339VItX1zB"
crossorigin="anonymous"&gt;&lt;/script&gt;
Expand Down Expand Up @@ -463,7 +468,7 @@ spec: SHA2; urlPrefix: http://csrc.nist.gov/publications/fips/fips180-4/fips-180
applied only to the `hash-expression` that immediately precedes it.

In order for user agents to remain fully forwards compatible with future
options, the user agent MUST ignore all unrecognized `option-expression`s.
options, the user agent MUST ignore all unrecognized `option-expression`s.

Note: Note that while the `option-expression` has been reserved in the syntax,
no options have been defined. It is likely that a future version of the spec
Expand All @@ -472,7 +477,7 @@ spec: SHA2; urlPrefix: http://csrc.nist.gov/publications/fips/fips180-4/fips-180

## Handling integrity violations ## {#handling-integrity-violations}

The user agent will refuse to render or execute responses that fail an integrity
The user agent MUST refuse to render or execute responses that fail an integrity
check, instead returning a network error as defined in Fetch [[!Fetch]].

Note: On a failed integrity check, an `error` event is fired. Developers
Expand Down Expand Up @@ -511,8 +516,8 @@ spec: SHA2; urlPrefix: http://csrc.nist.gov/publications/fips/fips180-4/fips-180
the digest in-flight (or remove it entirely, or do absolutely anything else to
the document), just as they could alter the response the hash is meant to
validate. Thus, it is recommended that authors deliver integrity metadata only
to a <a>Secure Context</a>. See also <a
href="http://www.w3.org/2001/tag/doc/web-https ">Securing the Web</a>.
to a <a>Secure Context</a>. See also <a
href="http://www.w3.org/2001/tag/doc/web-https">Securing the Web</a>.

## Hash collision attacks ## {#hash-collision-attacks}

Expand Down Expand Up @@ -558,6 +563,82 @@ spec: SHA2; urlPrefix: http://csrc.nist.gov/publications/fips/fips180-4/fips-180

<!-- ####################################################################### -->

# Authoring Considerations # {#authoring-considerations}

<em>This section is not normative.</em>

## Versioned resources ## {#versioned-resources}

<a>Integrity metadata</a> is only useful if the resource can be reasonably
expected to remain static, as dynamic resources will not have a
consistent hash over time. One strategy for ensuring consistency is to add
version numbers as part of the path or filename, which will change when the
resource is updated. A resource at a versioned URL can be expected to
remain static, and changes to these resources can be reasonably rejected
as potential evidence of compromise.

<div class="example">
<pre>
&lt;script src="https://example.com/v1.0/example-framework.js"
integrity="sha384-Li9vy3DqF8tnTXuiaAJuML3ky+er10rcgNR/VqsVpcw+ThHmYcwiB1pbOxEbzJr7"
crossorigin="anonymous"&gt;&lt;/script&gt;
</pre>
</div>

## Coping with errors ## {#coping-with-errors}

When an integrity violation is detected, the resource will not be parsed or
executed. This could cause problems for users, so the system should be
designed to cope with errors.

In response to an integrity error when loading a resource from a CDN or other
third-party server, the system could attempt to load a fallback resource from
a same-origin mirror.

<div class="example">
<pre>
&lt;script&gt;
document.addEventListener('error', error =&gt; {
const erroringScript = error.target;
if (erroringScript.hasAttribute('integrity')) {
const fallbackURL = erroringScript.getAttribute('src').replace(/https:\/\/.*?\//, '/');
const fallbackScript = document.createElement('script');
fallbackScript.setAttribute('src', fallbackURL);
erroringScript.after(fallbackScript);
}
}, true);
&lt;/script&gt;

&lt;script src="https://example.com/v1.0/example-framework.js"
integrity="sha384-Li9vy3DqF8tnTXuiaAJuML3ky+er10rcgNR/VqsVpcw+ThHmYcwiB1pbOxEbzJr7"
crossorigin="anonymous"&gt;&lt;/script&gt;
</pre>
</div>

Code that attempts to replace a third-party resource with a same-origin
mirror in the event of an error will need to be initialised before the
load attempt has been made.

It is worth evaluating if a same-origin resource may be a better choice in
the first place, instead of using a resource hosted on a third-party server.

If the resource cannot be made available to the system, then the system
should be built to cope as best as possible with the resource's absence. For
some resources, for example web fonts or non-essential styles, there may be
no work to do to leave the system in a usable state. Alternatively, the
system could be built using progressive enhancement principles, where in the
absence of a resource, or support from the user agent for that resource, the
system remains usable although potentially with degraded functionality.

If an alerting or logging system exists, the integrity error should also
be sent there so that appropriate steps can be taken. If a single resource
on a CDN is seen to have been modified, then general usage of that system
should be evaluated for other possible problems. For example, if other
resources without integrity metadata have also been loaded from the same CDN,
the impact of their potential modification should be evaluated.

<!-- ####################################################################### -->

# Acknowledgements # {#acknowledgements}

Much of the content here is inspired heavily by Gervase Markham's <a
Expand All @@ -567,5 +648,6 @@ spec: SHA2; urlPrefix: http://csrc.nist.gov/publications/fips/fips180-4/fips-180

A special thanks to Mike West for his invaluable contributions to the initial
version of this spec. Thanks to Brad Hill, Anne van Kesteren, Jonathan
Kingston, Mark Nottingham, Sergey Shekyan , Dan Veditz, Eduardo Vela,
Tanvi Vyas, and Michal Zalewski for providing invaluable feedback.
Kingston, Mark Nottingham, Sergey Shekyan, Dan Veditz, Eduardo Vela,
Tanvi Vyas, Robin Whittleton, and Michal Zalewski for providing invaluable
feedback.