demo · v131

CSP × Speculation-Rules header tester

Two surfaces deliver speculation rules: a <script type=speculationrules> element in HTML, and an HTTP Speculation-Rules response header. Pre-v131 both went through CSP script-src checks. v131 exempts the header. Pick a CSP and watch each surface verdict it.

inline script tag (still subject to CSP)

<script type="speculationrules">
{
  "prerender": [{ "where": { "href_matches": "/v131/*" } }]
}
</script>

Speculation-Rules header (v131: exempt)

HTTP/1.1 200 OK
Speculation-Rules: "/rules.json"

# rules.json
{
  "prerender": [{ "where": { "href_matches": "/v131/*" } }]
}

live header route

waiting for CSP selection...

    
  

why exempt the header

CSP's script-src directive exists to prevent injected <script> tags. A response header isn't injectable from page content; it's set by the server that already controls the bytes of the response. Applying script-src to it conflated two separate threat models. v131 fixes that.

see also