Skip to content

Integrate with speculation rules - #808

Open
vickiez wants to merge 5 commits into
w3c:mainfrom
vickiez:external-spec-rules
Open

vickiez wants to merge 5 commits into
w3c:mainfrom
vickiez:external-spec-rules

Conversation

@vickiez

@vickiez vickiez commented Mar 13, 2026 •

Copy link
Copy Markdown

Adds the following:

From #776:

  • Handling of the new "speculationrules" request destination, which is used by the Speculation-Rules HTTP header

New additions:

  • New speculation-rules-src fetch directive that restricts the sources from which speculation rules may be loaded, whether via <script> elements or the Speculation-Rules HTTP response header
  • Fallback chain: speculation-rules-src → script-src-elem → script-src → default-src, applied uniformly to both inline and external speculation rules
  • Handling of the "speculationrules" request destination now returns speculation-rules-src (removing the previous header exemption that returned null).

This reflects the agreed plan from whatwg/html#11697


Preview | Diff

domenic and others added 3 commits April 1, 2026 14:03
This upstreams the monkeypatches from https://wicg.github.io/nav-speculation/speculation-rules.html#content-security-policy. At a high level, the additions are:

- A new directive, `inline-speculation-rules`, which can be used if developers want to block inline JavaScript `<script>`s but allow inline `<script type=speculationrules>`s. This is done by introducing a new script type, `script speculationrules`, to sit alongside the existing `script` and `script attribute` types; HTML passes this new value in.

- Handling of the new `"speculationrules"` request destination, which is used by the `Speculation-Rules` HTTP header. It cannot be blocked by CSP.
@vickiez
vickiez force-pushed the external-spec-rules branch from 22806ee to 4e8aad7 Compare April 1, 2026 21:05
@vickiez
vickiez marked this pull request as ready for review April 1, 2026 21:05
@antosart

antosart commented Apr 2, 2026

Copy link
Copy Markdown
Member

We don't need the keyword inline-speculation-rules if we have speculation-rules-src, no? Developers will just be able to specify speculation-rules src 'unafe-inline'; script-src 'none' or something. I think having both is just confusing.

@hiroshige-g

hiroshige-g commented May 8, 2026 •

Copy link
Copy Markdown

IIUC (please correct me if wrong) this PR contains a major behavior changes that would break existing websites without updates to pages' CSP :
Applying speculation-rules-src CSP directive to Speculation-Rules header-initiated requests to external speculation-rules JSON files (while previously CSP is exempted per https://chromestatus.com/feature/5123809745829888).

To avoid breakage, pages should e.g. add speculation-rules-src directive that allows the requests to the JSON files if the pages have e.g. script-src CSP directives that would forbid the requests (which is likely).

cc/ @tunetheweb @nhiroki WDYT?

FYI Also see whatwg/html#11697 (comment) whatwg/html#11697 (comment) and around for previous context for direction/planning around external speculation rules.

@hiroshige-g

Copy link
Copy Markdown

Also this PR applies speculation-rules-src CSP directive instead of script-src-elem to <script type="speculationrules"> (i.e. inline speculation rules).
This would keep the existing behavior (because we'll anyway fallback to script-src-elem), if pages already have speculation-rules-src CSP directive (which is unlikely). This just opens a new option to specify speculation-rules-src without affecting more general script-src-elem.

@tunetheweb

tunetheweb commented May 8, 2026 •

Copy link
Copy Markdown
Member

Yes I thought we’d previously agreed that the HTTP Header version was out of scope? Because if you’ve the ability to set HTTP Headers then you’ve no guarantees on CSP anyway (since that is also usually set via HTTP Headers).

Also can I understand what this does for inline-speculation-rules for <script type="speculationrules">? Is this replacing that with the new speculation-rules-src: unsafe-inline directive? That would cause breakage to anyone who’s already deployed this under the old name so we need to check the web compatibility of any such change.

@annevk

annevk commented May 10, 2026

Copy link
Copy Markdown
Member

CSP should apply to links in HTTP headers as well to remain consistent.

@vickiez

vickiez commented Aug 3, 2026

Copy link
Copy Markdown
Author

Hi all, based on the latest discussion here, particularly the concern about breaking existing pages (#808 (comment)), I propose this revised plan to avoid breakage until speculation-rules-src is available. (Previous plan: whatwg/html#11697 (comment))

Stage 1 - external <script type=speculationrules> (whatwg/html#11697, whatwg/fetch#1841, CL)

  • Script element, inline and external: script-src-elem -> script-src -> default-src
  • Speculation-Rules header: exempt, unchanged from what ships today

Stage 2 - speculation-rules-src (this PR)

  • Both paths: speculation-rules-src -> script-src-elem -> script-src -> default-src
  • Pages affected by the header change can add speculation-rules-src

Note on inline-speculation-rules: inline rules would check as type script speculationrules, so an existing script-src-elem 'inline-speculation-rules' keeps working through the fallback chain. For speculation-rules-src, 'unsafe-inline' will have the same behavior.

What do you all think? If this sounds right, I can proceed with updating the specs and CL for Stage 1.

@hiroshige-g

Copy link
Copy Markdown

The incremental approach looks good to me (it's more like whatwg/html#11697 (comment) ), but I defer to @tunetheweb (speculation rules ecosystem) and @antosart (CSP) for details -- WDYT?

Comment thread index.bs
@antosart

Copy link
Copy Markdown
Member

Wrt your proposed plan, I believe it mostly applies to your implementation:

  • inline-speculation-rules is not defined in the spec, so I am not sure if you are referring to an implementation there. I believe the plan is that we won't define inline-speculation-rules in the specification.

  • The two stages approach also seems implementation specific. The spec change as is should apply both to the header and to the <script> element, assuming the hooks in fetch are correct.

If that's correct, the spec change looks fine to me modulo the comment above.

@vickiez

vickiez commented Aug 21, 2026

Copy link
Copy Markdown
Author

Wrt your proposed plan, I believe it mostly applies to your implementation:

  • inline-speculation-rules is not defined in the spec, so I am not sure if you are referring to an implementation there. I believe the plan is that we won't define inline-speculation-rules in the specification.
  • The two stages approach also seems implementation specific. The spec change as is should apply both to the header and to the <script> element, assuming the hooks in fetch are correct.

If that's correct, the spec change looks fine to me modulo the comment above.

@antosart I believe we are on the same page, we won't define inline-speculation-rules and the current spec change applies to both the header and <script> element. I created a new PR for the fetch spec here reflecting the latest changes: whatwg/fetch#1952

@tunetheweb

Copy link
Copy Markdown
Member

From my perspective this is a step backwards rather than forwards, for a number of reasons:

  • speculation-rules-src 'unsafe-inline' encourages the use of unsafe keyword. Is there a "safe" version of this (with nonce and/or hashes)? Or is the unsafe-inline the only way of using this in inline HTML? Does this mean we're effectively either encouraging the use of unsafe=inline or suggesting developers should use <script type="speculationrules" src="..."> and/or HTTP over inline HTML? Either way it seems like a regression over the current state when the aim if specifying this over it's own directive was to make it easier to deploy while allowing/not discouraging stricter script-src values.
  • It's still not clear to me why we need this for HTTP header version. Previously the thinking (at least from Google's side) was that that CSP's main scope was HTML since those with access to set HTTP headers already have the keys to the kingdom. Though I see from Add the "speculationrules" destination whatwg/fetch#1841 (comment) that that discussion remained unresolved. My main concern here is that this removes the main use case of the HTTP version of speculation rules — CDN auto-speculating for their customers. This is a huge part of speculation rules with the likes of Shopify and Cloudflare benefiting large volumes of their customers with this feature. Gating that behind CSP requires them to check and edit any existing CSP headers to add this which seems risky to me, and creates friction (which was why we decided to remove this initially, after investigating the risks and protection of what CSP realistically protects against). That's not to say that maybe should be the case, but I think it needs more discussion, perhaps with those platforms involved.

I agree <script type="speculationrules" src="..."> requires some CSP, and inline-speculation-rules seems weird to reuse for that since it's not inline, so speculation-rules-src does make sense. However, I'm not sure if we shouldn't keep inline-speculation-rules for the main use case, and have that act as a short cut of meaning speculation-rules-src 'unsafe-inline' 1) to avoid overly encouraging the use of unsafe-inline AND 2) reducing compat risk of introducing change here.

As to the whether HTTP Header Speculation Rules should be subject to CSP at all, that seems a separate conversation to what @vickiez seems interested in solving here (<script type="speculationrules" src="...">), and one we don't have agreement on yet.

@vickiez

vickiez commented Aug 28, 2026

Copy link
Copy Markdown
Author

I see what you mean, I have no objection to adding 'inline-speculation-rules' for script-src if only supporting speculation-rules-src 'unsafe-inline' encourages developers to choose other methods instead of inline speculation rules. We want to make inline speculation rules easy to allow while still supporting stricter methods, and nonces and hashes apply to inline rules in this change.

Thanks for providing the customer context for exempting the header, I’ll revive the conversation on the Fetch spec. For now, can we proceed with the speculation-rules-src addition and apply it to the HTTP header in a follow-up if we reach agreement to cover it? @tunetheweb @antosart

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants