Browser Security Best Practices

Chapter 2 · Practice 2 of 3

Use hashes when pages are static or cached

From Content Security Policy

Why it matters

A nonce must change on every response, which does not work for pages served from a CDN cache or built as static HTML. For those, OWASP describes a hash-based policy: list the hash of each allowed inline script.

Content-Security-Policy: script-src 'sha256-V2kaaafImTjn8RQTWZmF4IfGfQ7Qsqsw9GWaFjzFNPg=' 'strict-dynamic'; object-src 'none'; base-uri 'none';

Things to know:

  • Any change to the script, including whitespace from a formatter, changes the hash, so generate hashes in the build, not by hand.
  • The browser's console shows the expected hash in its violation message, which helps while debugging.
  • Combine with 'strict-dynamic' so a small hashed loader can load your bundles.
  • External script files can be covered by moving their loading into a hashed inline loader, or by subresource integrity.

If your framework renders most pages statically, hash-based CSP is usually the cleaner fit; for fully dynamic server rendering, nonces are simpler.