Living Standard — Last Updated 23 July 2025
X-Frame-Options
` headerRefresh
` headerSpeculative loading is the practice of performing navigation actions, such as prefetching, ahead of navigation starting. This makes subsequent navigations faster.
Developers can initatiate speculative loads by using speculation rules. User agents might also perform speculative loads in certain implementation-defined scenarios, such as typing into the address bar.
Speculation rules are how developers instruct the browser about speculative loading operations that the developer believes will be beneficial. They are delivered as JSON documents, via either:
inline script
elements with their type
attribute set to "speculationrules
"; or
resources fetched from a URL specified in the `Speculation-Rules
` HTTP
response header.
The following JSON document is parsed into a speculation rule set specifying a number of desired conditions for the user agent to start a referrer-initiated navigational prefetch:
{
"prefetch": [
{
"urls": ["/chapters/5"]
},
{
"eagerness": "moderate",
"where": {
"and": [
{ "href_matches": "/*" },
{ "not": { "selector_matches": ".no-prefetch" } }
]
}
}
]
}
A JSON document representing a speculation rule set must meet the following speculation rule set authoring requirements:
It must be valid JSON. [JSON]
The JSON must represent a JSON object, with at most three keys "tag
",
"prefetch
" and "prerender
".
In this standard, "prerender
" is optionally converted to
"prefetch
" at parse time. Some
implementations might implement different behavior for prerender, as specified in
Speculation Rules. [SPECULATIONRULES]
The value corresponding to the "tag
" key, if present, must be a
speculation rule tag.
The values corresponding to the "prefetch
" and "prerender
" keys, if present, must be arrays of valid speculation rules.
A valid speculation rule is a JSON object that meets the following requirements:
It must have at most the following keys: "source
", "urls
", "where
", "relative_to
",
"eagerness
", "referrer_policy
", "tag
", "requires
", "expects_no_vary_search
", or "target_hint
".
In this standard, "target_hint
" is ignored.
The value corresponding to the "source
" key, if present, must be
either "list
" or "document
".
If the value corresponding to the "source
" key is "list
", then the "urls
" key must be present, and the
"where
" key must be absent.
If the value corresponding to the "source
" key is "document
", then the "urls
" key must be absent.
The "urls
" and "where
" keys must not both be
present.
If the value corresponding to the "source
" key is "document
" or the "where
" key is present, then the "relative_to
" key must be absent.
The value corresponding to the "urls
" key, if present, must be an
array of valid URL strings.
The value corresponding to the "where
" key, if present, must be a
valid document rule predicate.
The value corresponding to the "relative_to
" key, if present, must
be either "ruleset
" or "document
".
The value corresponding to the "eagerness
" key, if present, must be
a speculation rule eagerness.
The value corresponding to the "referrer_policy
" key, if present,
must be a referrer policy.
The value corresponding to the "tag
" key, if present, must be a
speculation rule tag.
The value corresponding to the "requires
" key, if present, must be
an array of speculation rule
requirements.
The value corresponding to the "expects_no_vary_search
" key, if
present, must be a string that is parseable as a `No-Vary-Search
` header value.
A valid document rule predicate is a JSON object that meets the following requirements:
It must contain exactly one of the keys "and
", "or
", "not
", "href_matches
", or
"selector_matches
".
It must not contain any keys apart from the above or "relative_to
".
If it contains the key "relative_to
", then it must also contain the
key "href_matches
".
The value corresponding to the "relative_to
" key, if present, must
be either "ruleset
" or "document
".
The value corresponding to the "and
" or "or
"
keys, if present, must be arrays of valid document
rule predicates.
The value corresponding to the "not
" key, if present, must be a
valid document rule predicate.
The value corresponding to the "href_matches
" key, if present, must
be either a valid URL pattern input or an array of valid URL pattern inputs.
The value corresponding to the "selector_matches
" key, if present,
must be either a string matching <selector-list>
or an array of
strings that match <selector-list>
.
A valid URL pattern input is either:
a scalar value string that can be successfully parsed as a URL pattern constructor string, or;
a JSON object whose keys are drawn from the members of the URLPatternInit
dictionary and whose values are scalar value
strings.
A speculation rule set is a struct with the following items:
prefetch rules, a list of speculation rules, initially empty
In the future, other rules will be possible, e.g., prerender rules. See Speculation Rules for such not-yet-accepted extensions. [SPECULATIONRULES]
A speculation rule is a struct with the following items:
URLs, an ordered set of URLs
predicate, a document rule predicate or null
eagerness, a speculation rule eagerness
referrer policy, a referrer policy
tags, an ordered set of speculation rule tags
requirements, an ordered set of speculation rule requirements
No-Vary-Search hint, a URL search variance
A document rule predicate is one of the following:
A document rule conjunction is a struct with the following items:
clauses, a list of document rule predicates
A document rule disjunction is a struct with the following items:
clauses, a list of document rule predicates
A document rule negation is a struct with the following items:
clause, a document rule predicate
A document rule URL pattern predicate is a struct with the following items:
patterns, a list of URL patterns
A document rule CSS selector predicate is a struct with the following items:
A speculation rule eagerness is one of the following strings:
immediate
"The developer believes that performing the associated speculative loads is very likely to be worthwhile, and they might also expect that load to require significant lead time to complete. User agents should usually enact the speculative load candidate as soon as practical, subject only to considerations such as user preferences, device conditions, and resource limits.
eager
"User agents should enact the speculative load candidate on even a slight suggestion that the user may navigate to this URL in the future. For instance, the user might have moved the cursor toward a link or hovered it, even momentarily, or paused scrolling when the link is one of the more prominent ones in the viewport. The author is seeking to capture as many navigations as possible, as early as possible.
moderate
"User agents should enact the candidate if user behavior suggests the user may navigate to
this URL in the near future. For instance, the user might have scrolled a link into the viewport
and shown signs of being likely to click it, e.g., by moving the cursor over it for some time.
The developer is seeking a balance between "eager
" and
"conservative
".
conservative
"User agents should enact the candidate only when the user is very likely to navigate to this URL at any moment. For instance, the user might have begun to interact with a link. The developer is seeking to capture some of the benefits of speculative loading with a fairly small tradeoff of resources.
A speculation rule eagerness A is less eager than another speculation rule eagerness B if A follows B in the above list.
A speculation rule eagerness A is at least as eager as another speculation rule eagerness B if A is not less eager than B.
A speculation rule tag is either an ASCII string whose code points are all in the range U+0020 to U+007E inclusive, or null.
This code point range restriction ensures the value can be sent in an HTTP header with no escaping or modification.
A speculation rule requirement is the string "anonymous-client-ip-when-cross-origin
".
In the future, more possible requirements might be defined.
Since speculative loading is a progressive enhancement, this standard is fairly conservative in its parsing behavior. In particular, unknown keys or invalid values usually cause parsing failure, since it is safer to do nothing than to possibly misinterpret a speculation rule.
That said, parsing failure for a single speculation rule still allows other speculation rules to be processed. It is only in the case of top-level misconfiguration that the entire speculation rule set is discarded.
To parse a speculation rule set string given a string input,
a Document
document, and a URL baseURL:
Let parsed be the result of parsing a JSON string to an Infra value given input.
If parsed is not a map, then throw a
TypeError
indicating that the top-level value needs to be a JSON object.
Let result be a new speculation rule set.
Let tag be null.
If parsed["tag
"] exists:
If parsed["tag
"] is not a speculation rule
tag, then throw a TypeError
indicating that the speculation rule tag is
invalid.
Set tag to parsed["tag
"].
Let typesToTreatAsPrefetch be « "prefetch
" ».
The user agent may append "prerender
" to typesToTreatAsPrefetch.
Since this specification only includes prefetching, this allows user agents to treat requests for prerendering as requests for prefetching. User agents which implement prerendering, per the Speculation Rules specification, will instead interpret these as prerender requests. [SPECULATIONRULES]
For each type of typesToTreatAsPrefetch:
If parsed[type] exists:
If parsed[type] is a list, then for each rule of parsed[type]:
Let rule be the result of parsing a speculation rule given rule, tag, document, and baseURL.
If rule is null, then continue.
Append rule to result's prefetch rules.
Otherwise, the user agent may report a warning to the console indicating that the rules list for type needs to be a JSON array.
Return result.
To parse a speculation rule given a map
input, a speculation rule tag rulesetLevelTag, a
Document
document, and a URL baseURL:
If input is not a map:
The user agent may report a warning to the console indicating that the rule needs to be a JSON object.
If input has any key other than "source
", "urls
", "where
", "relative_to
", "eagerness
", "referrer_policy
", "tag
", "requires
", "expects_no_vary_search
", or "target_hint
":
The user agent may report a warning to the console indicating that the rule has unrecognized keys.
Return null.
"target_hint
" has no impact on the processing model in this standard. However,
implementations of Speculation Rules can use it for prerendering rules, and so
requiring user agents to fail parsing such rules would be counterproductive.
[SPECULATIONRULES].
Let source be null.
If input["source
"] exists, then set source to input["source
"].
Otherwise, if input["urls
"] exists and input["where
"] does not exist, then set source to "list
".
Otherwise, if input["where
"] exists and input["urls
"] does not exist, then set source to "document
".
If source is neither "list
" nor "document
":
The user agent may report a warning to the console indicating that a source could not be inferred or an invalid source was specified.
Return null.
Let urls be an empty list.
Let predicate be null.
If source is "list
":
If input["where
"] exists:
The user agent may report a warning to the console indicating that there were conflicting sources for this rule.
Return null.
If input["urls
"] does not exist, is not a list, or has any item that is not a string:
The user agent may report a warning to the console indicating that the supplied URL list was invalid.
Return null.
If input["relative_to
"] exists:
If input["relative_to
"] is neither "ruleset
" nor "document
":
The user agent may report a warning to the console indicating that the supplied relative-to value was invalid.
Return null.
If input["relative_to
"] is "document
", then set baseURL to document's
document base URL.
For each urlString of input["urls
"]:
Let parsedURL be the result of URL parsing urlString with baseURL.
If parsedURL is failure, or parsedURL's scheme is not an HTTP(S) scheme:
The user agent may report a warning to the console indicating that the supplied URL string was invalid.
Append parsedURL to urls.
If source is "document
":
If input["urls
"] or input["relative_to
"] exists:
The user agent may report a warning to the console indicating that there were conflicting sources for this rule.
Return null.
If input["where
"] does not exist, then set predicate to a document rule
conjunction whose clauses is an empty
list.
Such a predicate will match all links.
Otherwise, set predicate to the result of parsing a document rule predicate given input["where
"], document, and baseURL.
If predicate is null, then return null.
Let eagerness be "immediate
" if
source is "list
"; otherwise, "conservative
".
If input["eagerness
"] exists:
If input["eagerness
"] is not a speculation rule
eagerness:
The user agent may report a warning to the console indicating that the eagerness was invalid.
Return null.
Set eagerness to input["eagerness
"].
Let referrerPolicy be the empty string.
If input["referrer_policy
"] exists:
If input["referrer_policy
"] is not a referrer
policy:
The user agent may report a warning to the console indicating that the referrer policy was invalid.
Return null.
Set referrerPolicy to input["referrer_policy
"].
Let tags be an empty ordered set.
If rulesetLevelTag is not null, then append rulesetLevelTag to tags.
If input["tag
"] exists:
If input["tag
"] is not a speculation rule
tag:
The user agent may report a warning to the console indicating that the tag was invalid.
Return null.
Append input["tag
"]
to tags.
Let requirements be an empty ordered set.
If input["requires
"] exists:
If input["requires
"] is not a list:
The user agent may report a warning to the console indicating that the requirements were not understood.
Return null.
For each requirement of
input["requires
"]:
If requirement is not a speculation rule requirement:
The user agent may report a warning to the console indicating that the requirement was not understood.
Return null.
Append requirement to requirements.
Let noVarySearchHint be the default URL search variance.
If input["expects_no_vary_search
"] exists:
If input["expects_no_vary_search
"] is not a
string:
The user agent may report a warning to the console indicating that the
`No-Vary-Search
` hint was invalid.
Return null.
Set noVarySearchHint to the result of parsing a URL search variance given input["expects_no_vary_search
"].
Return a speculation rule with:
To parse a document rule predicate given a value input, a
Document
document, and a URL baseURL:
If input is not a map:
The user agent may report a warning to the console indicating that the document rule predicate was invalid.
Return null.
If input does not contain exactly one of "and
", "or
", "not
", "href_matches
", or "selector_matches
":
The user agent may report a warning to the console indicating that the document rule predicate was empty or ambiguous.
Return null.
Let predicateType be the single key found in the previous step.
If predicateType is "and
" or "or
":
If input has any key other than predicateType:
The user agent may report a warning to the console indicating that the document rule predicate had unexpected extra options.
Return null.
If input[predicateType] is not a list:
The user agent may report a warning to the console indicating that the document rule predicate had an invalid clause list.
Return null.
Let clauses be an empty list.
For each rawClause of input[predicateType]:
Let clause be the result of parsing a document rule predicate given rawClause, document, and baseURL.
If clause is null, then return null.
Append clause to clauses.
If predicateType is "and
", then return a
document rule conjunction whose clauses is
clauses.
Return a document rule disjunction whose clauses is clauses.
If predicateType is "not
":
If input has any key other than "not
":
The user agent may report a warning to the console indicating that the document rule predicate had unexpected extra options.
Return null.
Let clause be the result of parsing a document rule predicate given input[predicateType], document, and baseURL.
If clause is null, then return null.
Return a document rule negation whose clause is clause.
If predicateType is "href_matches
":
If input has any key other than "href_matches
" or "relative_to
":
The user agent may report a warning to the console indicating that the document rule predicate had unexpected extra options.
Return null.
If input["relative_to
"] exists:
If input["relative_to
"] is neither "ruleset
" nor "document
":
The user agent may report a warning to the console indicating that the supplied relative-to value was invalid.
Return null.
If input["relative_to
"] is "document
", then set baseURL to document's
document base URL.
Let rawPatterns be input["href_matches
"].
If rawPatterns is not a list, then set rawPatterns to « rawPatterns ».
Let patterns be an empty list.
For each rawPattern of rawPatterns:
Let pattern be the result of building a URL pattern from an Infra value given rawPattern and baseURL. If this step throws and exception, catch the exception and set pattern to null.
If pattern is null:
The user agent may report a warning to the console indicating that the supplied URL pattern was invalid.
Return null.
Append pattern to patterns.
Return a document rule URL pattern predicate whose patterns is patterns.
If predicateType is "selector_matches
":
If input has any key other than "selector_matches
":
The user agent may report a warning to the console indicating that the document rule predicate had unexpected extra options.
Return null.
Let rawSelectors be input["selector_matches
"].
If rawSelectors is not a list, then set rawSelectors to « rawSelectors ».
Let selectors be an empty list.
For each rawSelector of rawSelectors:
Let parsedSelectorList be failure.
If rawSelector is a string, then set parsedSelectorList to the result of parsing a selector given rawSelector.
If parsedSelectorList is failure:
The user agent may report a warning to the console indicating that the supplied selector list was invalid.
Return null.
For each selector of parsedSelectorList, append selector to selectors.
Return a document rule CSS selector predicate whose selectors is selectors.
Assert: this step is never reached, as one of the previous branches was taken.
A speculative load candidate is a struct with the following items:
URL, a URL
No-Vary-Search hint, a URL search variance
eagerness, a speculation rule eagerness
referrer policy, a referrer policy
tags, an ordered set of speculation rule tags
A prefetch candidate is a speculative load candidate with the following additional item:
anonymization policy, a prefetch IP anonymization policy
A prefetch IP anonymization policy is either null or a cross-origin prefetch IP anonymization policy.
A cross-origin prefetch IP anonymization policy is a struct whose single item is its origin, an origin.
A speculative load candidate candidateA is redundant with another speculative load candidate candidateB if the following steps return true:
If candidateA's No-Vary-Search hint is not equal to candidateB's No-Vary-Search hint, then return false.
If candidateA's URL is not equivalent modulo search variance to candidateB's URL given candidateA's No-Vary-Search hint, then return false.
Return true.
The requirement that the No-Vary-Search hints be equivalent is somewhat strict. It means that some cases which could theoretically be treated as matching, are not treated as such. Thus, redundant speculative loads could happen.
However, allowing more lenient matching makes the check no longer an equivalence relation, and producing such matches would require an implementation strategy that does a full comparison, instead of a simpler one using normalized URL keys. This is in line with the best practices for server operators, and attendant HTTP cache implementation notes, in No Vary Search § 6 Comparing.
In practice, we do not expect this to cause redundant speculative loads, since server
operators and the corresponding speculation rules-writing web developers will follow best
practices and use static `No-Vary-Search
` header values/speculation rule hints.
Consider three speculative load candidates:
A has a URL of https://example.com?a=1&b=1
and a No-Vary-Search hint parsed from params=("a")
.
B has a URL of https://example.com?a=2&b=1
and a No-Vary-Search hint parsed from params=("b")
.
C has a URL of https://example.com?a=2&b=2
and a No-Vary-Search hint parsed from params=("a")
.
With the current definition fo redundant with, none of these candidates are redundant with each other. A speculation rule set which contained all three could cause three separate speculative loads.
A definition which did not require equivalent No-Vary-Search hints could consider A and B to match (using A's No-Vary-Search hint), and B and C to match (using B's No-Vary-Search hint). But it could not consider A and C to match, so it would not be transitive, and thus not an equivalence relation.
To collect tags for matching speculative load candidates given a speculative load candidate candidateUnderConsideration and a list of speculative load candidates allCandidates:
Let tags be an empty ordered set.
For each candidate of allCandidates:
If candidate is not redundant with candidateUnderConsideration, then continue.
If candidate's eagerness is less eager than candidateUnderConsideration's eagerness, then continue.
Sort in ascending order tags, with tagA being less than tagB if tagA is null, or if tagA is code unit less than tagB.
Return tags.
Every Document
has speculation rule sets, a
list of speculation rule sets, initially
empty.
Every Document
has a consider speculative loads microtask queued, a
boolean, initially false.
To consider speculative loads for a Document
document:
If document's node navigable is not a top-level traversable, then return.
Supporting speculative loads into child navigables has some complexities and is not currently defined. It might be possible to define it in the future.
If document's consider speculative loads microtask queued is true, then return.
Set document's consider speculative loads microtask queued to true.
Queue a microtask given document to run the following steps:
Set document's consider speculative loads microtask queued to false.
Run the inner consider speculative loads steps for document.
In addition to the call sites explicitly given in this standard, when style recalculation would
cause selector matching results to change, the user agent must consider speculative
loads for the relevant Document
.
In this standard, every call to consider speculative loads is given
just a Document
, and the algorithm re-computes all possible candidates in a stateless
way. A real implementation would likely cache previous computations, and pass along information
from the call site to make updates more efficient. For example, if an a
element's
href
attribute is changed, that specific element could
be passed along in order to update only the related speculative load candidate.
The inner consider speculative loads steps for a Document
document are:
If document is not fully active, then return.
Let prefetchCandidates be an empty list.
For each ruleSet of document's speculation rule sets:
For each rule of ruleSet's prefetch rules:
Let anonymizationPolicy be null.
If rule's requirements contains "anonymous-client-ip-when-cross-origin
", then set
anonymizationPolicy to a cross-origin prefetch IP anonymization
policy whose origin is document's origin.
Let referrerPolicy be the result of computing a speculative load referrer policy given rule and null.
Append a new prefetch candidate with
to prefetchCandidates.
If rule's predicate is not null:
Let links be the result of finding matching links given document and rule's predicate.
For each link of links:
Let referrerPolicy be the result of computing a speculative load referrer policy given rule and link.
Append a new prefetch candidate with
to prefetchCandidates.
For each prefetchRecord of document's prefetch records:
If prefetchRecord's source is
not "speculation rules
", then continue.
If prefetchRecord is not still being speculated given prefetchCandidates, then cancel and discard prefetchRecord given document.
For each prefetchCandidate of prefetchCanddiates:
The user agent may run the following steps:
Let tagsToSend be the result of collecting tags for matching speculative load candidates given prefetchCandidate and prefetchCandidates.
Let prefetchRecord be a new prefetch record with
speculation rules
"Start a referrer-initiated navigational prefetch given prefetchRecord and document.
When deciding whether to execute this "may" step, user agents should consider prefetchCandidate's eagerness, in accordance to the current behavior of the user and the definitions of speculation rule eagerness.
prefetchCandidate's No-Vary-Search hint can also be useful in implementing the heuristics defined for the speculation rule eagerness values. For example, a user hovering of a link whose URL is equivalent modulo search variance to prefetchCandidate's URL given prefetchCandidate's No-Vary-Search hint could indicate to the user agent that performing this step would be useful.
If a user agent chooses to perform this step to enact prefetchCandidate, then the user agent must also perform this step to enact other candidates which are redundant with prefetchCandidate and whose eagerness is at least as eager as prefetchCandidate's eagerness. The first-encountered candidate in the prefetchCandidates list will win, and the others will be ignored by the start a referrer-initiated navigational prefetch algorithm. This gives deterministic behavior for web developers.
The following speculation rules generate two redundant prefetch candidates:
{
"prefetch": [
{
"tag": "a",
"urls": ["next.html"]
},
{
"tag": "b",
"urls": ["next.html"],
"referrer_policy": "no-referrer"
}
]
}
A user agent which follows the above requirement will enact both candidates, if it enacts
any. The second call to the start a referrer-initiated navigational prefetch
algorithm will end up doing nothing, and so the request will be made with the default
referrer policy, instead of using "no-referrer
".
However, the collect tags for matching speculative load candidates algorithm
will collect tags from both candidates, so the `Sec-Speculation-Tags
` header
will be set to "a", "b"
. This indicates to server operators that
either rule could have caused the speculative load.
When deciding whether to execute this "may" step, user agents should prioritize user preferences (express or implied, such as data-saver or battery-saver modes) over the eagerness supplied by the web developer.
To compute a speculative load referrer policy given a speculation rule
rule and an HTMLHyperlinkElementUtils
-or-null link:
If rule's referrer policy is not the empty string, then return rule's referrer policy.
If link is null, then return the empty string.
Return link's hyperlink referrer policy.
To find matching links given a Document
document and a
document rule predicate predicate:
Let links be an empty list.
For each shadow-including descendant descendant of document, in shadow-including tree order:
If descendant is not an a
or area
element with an
href
attribute, then continue.
If descendant is not being rendered or is part of skipped contents, then continue.
Such links, though present in document, aren't available for the user to interact with, and thus are unlikely to be good candidates. In addition, they might not have their style or layout computed, which might make CSS selector matching less efficient in user agents which skip some or all of that work for these elements.
If descendant's url is null, or its scheme is not an HTTP(S) scheme, then continue.
If predicate matches descendant, then append descendant to links.
Return links.
A document rule predicate predicate matches an HTMLHyperlinkElementUtils
el if the following steps return true:
If predicate is a document rule conjunction:
If predicate is a document rule disjunction:
If predicate is a document rule negation:
If predicate is a document rule URL pattern predicate:
If predicate is a document rule CSS selector predicate:
For each selector of predicate's selectors:
If performing a match given selector and el with the scoping root set to el's root returns sucess, then return true.
Return false.
Assert: this step is not reached.
Speculation rules features use the speculation rules task source.
Because speculative loading is generally less important than processing tasks for the purpose of the current document, implementations might give tasks enqueued here an especially low priority.
For now, the navigational prefetching process is defined in the Prefetch specification. Moving it into this standard is tracked in issue #11123. [PREFETCH]
This standard refers to the following concepts defined there:
Speculation-Rules
` headerThe `Speculation-Rules
` HTTP response header allows the
developer to request that the user agent fetch and apply a given speculation rule set
to the current Document
. It is a structured
header whose value must be a list of
strings that are all valid URL strings.
To process the `Speculation-Rules
` header given a Document
document and a response response:
Let parsedList be the result of getting a structured field value
given `Speculation-Rules
` and "list
" from
response's header list.
If parsedList is null, then return.
For each item of parsedList:
Let url be the result of URL parsing item with document's document base URL.
If url is failure, then continue.
Optionally, wait for an implementation-defined amount of time.
This allows the implementation to prioritize other work ahead of loading
speculation rules, as especially during Document
creation and header
processing, there are often many more important things going on.
Queue a task on the speculation rules task source to perform the following steps:
Let request be a new request whose
URL is url, client is document's relevant
settings object, destination is
"speculationrules
", and mode is "cors
".
Fetch request with the following processResponseConsumeBody steps given response response and null, failure, or a byte sequence bodyBytes:
If bodyBytes is null or failure, then abort these steps.
If response's status is not an ok status, then abort these steps.
If the result of extracting a MIME type
from response's header list
does not have an essence of
"application/speculationrules+json
", then abort these steps.
Let bodyText be the result of UTF-8 decoding bodyBytes.
Let ruleSet be the result of parsing a speculation rule set string given bodyText, document, and response's URL. If this throws an exception, then abort these steps.
Append ruleSet to document's speculation rule sets.
Consider speculative loads for document.
Sec-Speculation-Tags
` headerThe `Sec-Speculation-Tags
` HTTP request header specifies
the web developer-provided tags associated with the speculative navigation request. It can also be
used to distinguish speculative navigation requests from speculative subresource requests, since
`Sec-Purpose
` can be sent by both categories of requests.
The header is a structured header whose value must
be a list. The list can contain either token or string values. String values represent
developer-provided tags, whereas token values represent predefined tags. As of now, the only
predefined tag is null
, which indicates a speculative navigation request
with no developer-defined tag.
Speculative loads can be initiated by web pages to cross-site destinations. However, because such cross-site speculative loads are always done without credentials, as explained below, ambient authority is limited to requests that are already possible via other mechanisms on the platform.
The `Speculation-Rules
` header can also be used to issue requests. However, they
use the "same-origin
" credentials mode, the "cors
" mode, and responses which do not
use the application/speculationrules+json
MIME type essence are ignored,
so they are not useful in mounting attacks.
Because links in a document can be selected for speculative loading via document rule predicates, developers need to be cautious if such links might contain user-generated markup. Using a document rule CSS selector predicate to exclude such potentially-dangerous links, or using a document rule URL pattern predicate to allowlist known-safe links, are useful techniques in this regard.
As with all uses of the script
element, developers need to be cautious about
inserting user-provided content into <script type=speculationrules>
's
child text content. In particular, the insertion of an unescaped closing </script>
tag could be used to break out of the script
element
context and inject attacker-controlled markup.
The <script type=speculationrules>
feature causes activity in
response to content found in the document, so it is worth considering the options open to an
attacker able to inject unescaped HTML. Such an attacker is already able to inject JavaScript or
iframe
elements. Speculative loads are generally less dangerous than arbitrary script
execution. However, the use of document rule
predicates could be used to speculatively load links in the document, and the existence of
those loads could provide a vector for exfiltrating information about those links.
Defense-in-depth against this possibility is provided by Content Security Policy. In particular,
the script-src
directive can be used to restrict the parsing of speculation
rules script
elements, and the default-src
directive applies
to navigational prefetch requests arising from such speculation rules. Additional defense is
provided by the requirement that speculative loads are only performed to potentially-trustworthy URLs, so an on-path attacker would only
have access to metadata and traffic analysis, and could not see the URLs directly.
[CSP]
It's generally not expected that user-generated content will be added as arbitrary response
headers: server operators are already going to encounter significant trouble if this is possible.
It is therefore unlikely that the `Speculation-Rules
` header meaningfully expands the
XSS attack surface. For this reason, Content Security Policy does not apply to the loading of rule
sets via that header.
This standard allows developers to request that navigational prefetches are performed using IP anonymization technology provided by the user agent. The details of this anonymization are not specified, but some general security principles apply.
To the extent IP anonymization is implemented using a proxy service, it is advisable to minimize the information available to the service operator and other entities on the network path. This likely involves, at a minimum, the use of TLS for the connection.
Site operators need to be aware that, similar to virtual private network (VPN) technology, the client IP address seen by the HTTP server might not exactly correspond to the user's actual network provider or location, and a traffic for multiple distinct subscribers could originate from a single client IP address. This can affect site operators' security and abuse prevention measures. IP anonymization measures might make an effort to use an egress IP address which has a similar geolocation or is located in the same jurisdiction as the user, but any such behavior is particular to the user agent and not guaranteed.
The consider speculative loads algorithm contains a crucial "may" step, which encourages user agents to start referrer-initiated navigational prefetches based on a combination of the speculation rule eagerness and other features of the user's environment. Because it can be observable to the document whether speculative loads are performed, user agents must take care to protect privacy when making such decisions—for instance by only using information which is already available to the origin. If these heuristics depend on any persistent state, that state must be erased whenever the user erases other site data. If the user agent automatically clears other site data from time to time, it must erase such persistent state at the same time.
The use of origin instead of site here is intentional. Although same-site origins are generally allowed to coordinate if they wish, the web's security model is premised on preventing origins from accessing the data of other origins, even same-site ones. Thus, the user agent needs to be sure not to leak such data unintentionally across origins, not just across sites.
Examples of inputs which would be already known to the document:
author-supplied eagerness
order of appearance in the document
whether a link is in the viewport
whether the cursor is near a link
rendered size of a link
Examples of persistent data related to the origin (which the origin could have gathered itself) but which must be erased according to user intent:
whether the user has clicked this or similar links on this document or other documents on the same origin
Examples of device information which might be valuable in deciding whether speculative loading is appropriate, but which needs to be considered as part of the user agent's overall privacy posture because it can make the user more identifiable across origins:
coarse device class (CPU, memory)
coarse battery level
whether the network connection is known to be metered
any user-toggleable settings, such as a speculative loading toggle, a battery-saver toggle, or a data-saver toggle
The start a referrer-initiated navigational prefetch algorithm is designed to ensure that the HTTP requests that it issues behave consistently with how user agents partition credentials according to storage keys. This property is maintained even for cross-partition prefetches, as follows.
If a future navigation using a prefetched response would load a document in the same partition, then at prefetch time, the partitioned credentials can be sent, as they can with subresource requests and scripted fetches. If such a future navigation would instead load a document in another partition, it would be inconsistent with the partitioning scheme to use partitioned credentials for the destination partition (since this would cross the boundary between partitions without a top-level navigation) and also inconsistent to use partitioned credentials within the originating partition (since this would result in the user seeing a document with different state than a non-prefetched navigation). Instead, a third, initially empty, partition is used for such requests. These requests therefore send along no credentials from either partition. However, the resulting prefetched response body constructed using this initially-empty partition can only be used if, at activation time, the destination partition contains no credentials.
This is somewhat similar to the behavior of only sending such prefetch requests if the destination partition is known ahead of time to not contain credentials. However, to avoid such behavior being used a way of probing for the presence of credentials, instead such prefetch requests are always completed, and in the case of conflicting credentials, their results are not used.
Redirects are possible between these two types of requests. A redirect from a same- to cross-partition URL could contain information derived from partitioned credentials in the originating partition; however, this is equivalent to the originating document fetching the same-partition URL itself and then issuing a request for the cross-partition URL. A redirect from a cross- to same-origin URL could carry credentials from the isolated partition, but since this partition has no prior state this does not enable tracking based on the user's prior browsing activity on that site, and the document could construct the same state by issuing uncredentialed requests itself.
Speculative loads provide a mechanism through which HTTP requests for later top-level navigation can be made without a user gesture. It is natural to ask whether it is possible for two coordinating sites to connect user identities.
Since existing credentials for the destination site are not sent (as explained in
the previous section), that site is limited in its ability to identify the user before navigation
in a similar way to if the referrer site had simply used fetch()
to make an
uncredentialed request. Upon navigation, this becomes similar to ordinary navigation (e.g., by
clicking a link that was not speculatively loaded).
To the extent that user agents attempt to mitigate identity joining for ordinary fetches and navigations, they can apply similar mitigations to speculatively-loaded navigations.
X-Frame-Options
` headerSupport in all current engines.
The `X-Frame-Options
` HTTP response header is a way
of controlling whether and how a Document
may be loaded inside of a child
navigable. For sites using CSP, the frame-ancestors
directive provides more granular control over the
same situations. It was originally defined in HTTP Header Field X-Frame-Options, but
the definition and processing model here supersedes that document.
[CSP] [RFC7034]
In particular, HTTP Header Field X-Frame-Options specified an `ALLOW-FROM
` variant of the header, but that is not to be implemented.
Per the below processing model, if both
a CSP frame-ancestors
directive and an
`X-Frame-Options
` header are used in the same response, then `X-Frame-Options
` is ignored.
For web developers and conformance checkers, its value ABNF is:
X-Frame-Options = "DENY" / "SAMEORIGIN"
To check a navigation response's adherence to `X-Frame-Options
`, given
a response response, a navigable
navigable, a CSP list cspList, and
an origin destinationOrigin:
If navigable is not a child navigable, then return true.
For each policy of cspList:
If policy's disposition is not "enforce
", then continue.
If policy's directive set contains a frame-ancestors
directive, then return true.
Let rawXFrameOptions be the result of getting, decoding, and splitting
`X-Frame-Options
` from response's header list.
Let xFrameOptions be a new set.
For each value of rawXFrameOptions, append value, converted to ASCII lowercase, to xFrameOptions.
If xFrameOptions's size is greater than 1, and
xFrameOptions contains any of "deny
", "allowall
", or "sameorigin
", then return false.
The intention here is to block any attempts at applying
`X-Frame-Options
` which were trying to do something valid, but appear confused.
This is the only impact of the legacy `ALLOWALL
` value
on the processing model.
If xFrameOptions's size is greater than 1, then return true.
This means it contains multiple invalid values, which we treat the same way as if the header was omitted entirely.
If xFrameOptions[0] is "deny
", then return
false.
If xFrameOptions[0] is "sameorigin
", then:
Let containerDocument be navigable's container document.
While containerDocument is not null:
If containerDocument's origin is not same origin with destinationOrigin, then return false.
Set containerDocument to containerDocument's container document.
Return true.
If we've reached this point then we have a lone invalid value (which could
potentially be one the legacy `ALLOWALL
` or `ALLOW-FROM
` forms). These are treated as if the header were omitted
entirely.
The following table illustrates the processing of various values for the header, including non-conformant ones:
`X-Frame-Options ` | Valid | Result |
---|---|---|
`DENY ` | ✅ | embedding disallowed |
`SAMEORIGIN ` | ✅ | same-origin embedding allowed |
`INVALID ` | ❌ | embedding allowed |
`ALLOWALL ` | ❌ | embedding allowed |
`ALLOW-FROM=https://example.com/ ` | ❌ | embedding allowed (from anywhere) |
The following table illustrates how various non-conformant cases involving multiple values are processed:
`X-Frame-Options ` | Result |
---|---|
`SAMEORIGIN, SAMEORIGIN ` | same-origin embedding allowed |
`SAMEORIGIN, DENY ` | embedding disallowed |
`SAMEORIGIN, ` | embedding disallowed |
`SAMEORIGIN, ALLOWALL ` | embedding disallowed |
`SAMEORIGIN, INVALID ` | embedding disallowed |
`ALLOWALL, INVALID ` | embedding disallowed |
`ALLOWALL, ` | embedding disallowed |
`INVALID, INVALID ` | embedding allowed |
The same results are obtained whether the values are delivered in a single header whose value is comma-delimited, or in multiple headers.
Refresh
` headerThe `Refresh
` HTTP response header is the HTTP-equivalent
to a meta
element with an http-equiv
attribute in the Refresh state. It takes the same value and works largely the
same. Its processing model is detailed in create and initialize a Document
object.
Browser user agents should provide the ability to navigate, reload, and stop loading any top-level traversable in their top-level traversable set.
For example, via a location bar and reload/stop button UI.
Browser user agents should provide the ability to traverse by a delta any top-level traversable in their top-level traversable set.
For example, via back and forward buttons, possibly including long-press abilities to change the delta.
It is suggested that such user agents allow traversal by deltas greater than one, to avoid
letting a page "trap" the user by stuffing the session history with spurious entries. (For
example, via repeated calls to history.pushState()
or
fragment navigations.)
Some user agents have heuristics for translating a single "back" or "forward" button press into a larger delta, specifically to overcome such abuses. We are contemplating specifying these heuristics in issue #7832.
Browser user agents should offer users the ability to create a fresh top-level traversable, given a user-provided or user agent-determined initial URL.
For example, via a "new tab" or "new window" button.
Browser user agents should offer users the ability to arbitrarily close any top-level traversable in their top-level traversable set.
For example, by clicking a "close tab" button.
Browser user agents may provide ways for the user to explicitly cause any navigable (not just a top-level traversable) to navigate, reload, or stop loading.
For example, via a context menu.
Browser user agents may provide the ability for users to destroy a top-level traversable.
For example, by force-closing a window containing one or more such top-level traversables.
When a user requests a reload of a navigable whose active session history entry's document state's resource is a POST resource, the user agent should prompt the user to confirm the operation first, since otherwise transactions (e.g., purchases or database modifications) could be repeated.
When a user requests a reload of a navigable, user agents may provide a mechanism for ignoring any caches when reloading.
All calls to navigate initiated by the mechanisms mentioned above must have the userInvolvement argument set to "browser UI
".
All calls to reload initiated by the mechanisms mentioned above must have the userInvolvement argument set to "browser UI
".
All calls to traverse the history by a delta initiated by the mechanisms mentioned above must not pass a value for the sourceDocument argument.
The above recommendations, and the data structures in this specification, are not meant to place restrictions on how user agents represent the session history to the user.
For example, although a top-level traversable's session history entries are stored and maintained as a list, and the user agent is recommended to give an interface for traversing that list by a delta, a novel user agent could instead or in addition present a tree-like view, with each page having multiple "forward" pages that the user can choose between.
Similarly, although session history for all descendant navigables is stored in their traversable navigable, user agents could present the user with a more nuanced per-navigable view of the session history.
Browser user agents may use a top-level browsing context's is popup boolean for the following purposes:
Deciding whether or not to provide a minimal web browser user interface for the corresponding top-level traversable.
Performing the optional steps in set up browsing context features.
In both cases user agents might additionally incorporate user preferences, or present a choice as to whether to go down the popup route.
User agents that provides a minimal user interface for such popups are encouraged to not hide the browser's location bar.