demo · v141
URL Hashes
Pin a specific external script by hashing its URL — not its contents. Allows mutable scripts (analytics, telemetry) to keep updating without breaking SRI, while still locking down which URL the browser will execute. Type a URL below, the page computes the v2 CSP keyword for you.
SubtleCrypto in the page — exactly how a build pipeline would generate it. Older browsers ignore unknown CSP keywords gracefully, so you can ship the v2 policy alongside 'self' as a fallback.
before — host source
allows ANY path on the host. attacker who can upload /uploads/x.js to the same CDN wins.
after — url-hash (v2)
only THIS URL executes. content can change as the vendor updates the script.
how the hash is computed
// Identical to what a CI pipeline would do
async function urlHashKeyword(url) {
const buf = new TextEncoder().encode(url);
const digest = await crypto.subtle.digest("SHA-256", buf);
const b64 = btoa(String.fromCharCode(...new Uint8Array(digest)));
return `'url-sha256-${b64}'`;
}
// CSP header
// Content-Security-Policy: script-src 'url-sha256-AbCdEf…='
why this angle
The explainer's leading example is exactly this: analytics scripts and ad tags that update on a vendor's release cadence. Subresource Integrity locks the script contents, which breaks the next time the vendor pushes a fix. Host-source pins the hostname, which is much too broad — if the CDN ever hosts user-uploaded content, you've opened the door. URL hashes give you the missing middle ground: pin the exact URL, allow the contents to evolve.