Summary

  • W3C's first public Subresource Integrity draft appeared on 18 March 2014 and explored checking fetched resources against cryptographic digests. Its proposed list of elements was broader than the one that reached the 2016 Recommendation.
  • The 23 June 2016 Recommendation specified integrity metadata for scripts and stylesheet links. The browser compares an eligible response with the expected digest and refuses to execute or render a mismatch.

The script arrived at the right address. Its URL was familiar, its delivery punctual, and it had the easy confidence of a guest who had been invited many times. The page still had reason to ask what was inside the package. A changed JavaScript file can change what the page does. A changed stylesheet can change what readers see. The address tells the browser where to fetch; a digest tells it which version the page author expected.

The first public W3C Subresource Integrity Working Draft, published on 18 March 2014, began with that mismatch between location and content. It described a mechanism for checking a fetched resource with a cryptographic hash. The early draft sketched a wide list of elements that might carry integrity metadata, from scripts and stylesheets to images and frames. That was the workshop table, full of possibilities. The eventual standard would leave fewer tools on the bench.

By the 12 November 2015 Candidate Recommendation Snapshot, the design had narrowed around the integrity attribute on script and stylesheet link elements. The 23 June 2016 W3C Recommendation kept those two entry points. A publisher could put hash metadata beside the resource URL in the HTML. The browser would fetch the resource, compute the digest of the eligible response and compare it with the value supplied by the page. The check concerned the received content, the part a URL alone cannot describe.

The metadata names a hash function and its expected digest. The Recommendation required user agents to support SHA-256, SHA-384 and SHA-512 for this purpose. It also described how several integrity values could accompany one resource, with the strongest supported hash function taking precedence. This was a small piece of version discipline placed exactly at the boundary where an outside file becomes active code or presentation. The browser was handed an expectation rather than an instruction to trust whichever package reached the door.

Eligibility mattered too. In the 2016 rules, a same-origin response can be checked, as can a cross-origin response made readable through CORS. An opaque cross-origin response does not expose the bytes for this comparison. The page author therefore had to arrange both the expected digest and a response the browser could validate. The checksum was not a magic sticker slapped onto every third-party resource; it operated within the browser's fetch rules.

When the values disagree, the 2016 Recommendation directs the user agent to refuse to render or execute the response and report a network error. An error event lets the author arrange a fallback, perhaps a known local copy. That gives the page a clear answer to the familiar script that turned up with unfamiliar contents: this version does not enter. The site can then decide how to keep the reader's task working, instead of letting an unexpected file make that decision first.

The W3C publication history traces the 2014 first public draft through the 2015 candidate stage to the 2016 Recommendation. W3C's announcement on 23 June 2016 described the finished idea as verifying that a fetched resource arrived without unexpected manipulation. The change in scope across those documents matters: the 2014 draft's broad guest list became a 2016 browser check for scripts and stylesheet links.

There is a routine consequence for the publisher. If it deliberately updates the file, the expected digest must change with it; otherwise the browser will reject the new version as faithfully as it rejects an unwelcome alteration. The author controls which bytes are invited, and the browser performs the comparison. A URL gets the courier to the building. The fingerprint decides whether the parcel belongs at the party.