What does the sec-fetch-site header mean? Why is the Origin header undefined?
I have an API endpoint that I call from my React app. That API is on the same domain. … I was expecting to see an
Origin
header on my server logs.
Browsers send no Origin
in same-origin GET
requests, per Fetch spec requirements. ✳️
it's like the Origin check was already made
Yes — browsers know:
- the origin of the code making the request
- the origin of the resource for which the request is being made
- the request method
…and browsers check all those before deciding whether to add the Origin
header; and they don’t add the Origin
header if the origins match and the method is GET
.
// AND I ALSO GET THESE HEADERS "sec-fetch-dest":"empty", "sec-fetch-mode":"cors", "sec-fetch-site":"same-origin"
What do they mean? … For example: if I get
sec-fetch-site: cross-site
it means that the call was generate in another website/domain? Is that correct?
https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-site-header has details:
Sec-Fetch-Site value | What the value indicates |
---|---|
same-origin | The origin to which the request is being made matches the origin of the code making the request. |
same-site | The origin to which the request is being made and the origin of the code making the request have the same “registrable domain” (sometimes also referred to as the “same eTLD+1” or “same effective top-level domain plus one”); so, for example, https://subdomain.example.com and https://example.com are same-site (even though not same-origin). |
cross-site | The origin to which the request is being made and the origin of the code making the request are neither same-origin nor even same-site but instead have different registrable domains. |
none | The request wasn’t initiated programatically by frontend code (for example, not by an XHR/fetch/ajax call) but instead initiated by normal user navigation — that is, by a user doing something like directly putting an address into the browser URL bar, or clicking on a hyperlink. |
✳️ Spec requirements causing the Origin
header to be omitted in same-origin GET
requests:
Whether or not the Origin
header gets added ultimately depends on the request’s “response tainting”, the value of which starts out as "basic
", and which, for same-origin requests, the Fetch algorithm keeps sets to "basic
", per step 12 of the “Main fetch” algorithm:
↪ request’s current url’s origin is same origin with request’s origin, and request’s response tainting is "
basic
"
…
- Set request’s response tainting to "
basic
".
- Return the result of running scheme fetch given fetchParams.
Running scheme fetch causes the append a request `Origin` header algorithm to get invoked, and that causes the Origin
header to be added only if at least one of the following is true:
- the request’s response tainting is "
cors
" - the request’s mode is "
websocket
" - the request’s method is neither
GET
norHEAD
But for same-origin GET
, the response tainting isn’t cors
(rather, per the requirements above, it’s basic
), the request mode isn’t websocket
, and of course the method isn’t neither GET
nor HEAD
(it’s GET
); thus, the algorithm requires browsers to not add an Origin
header.
Comments
-
cbdeveloper almost 2 years
I have an
API
endpoint that I call from my React app. ThatAPI
is on the same domain. Something like:https://www.example.com https://www.example.com/api/update-something
I use
cross-fetch
to do that request.I was expecting to see an
Origin
header on my server logs. Infact, I was expecting to seeOrigin: https://www.example.com
.But here is what I get:
Origin: undefined // AND I ALSO GET THESE HEADERS "sec-fetch-dest":"empty", "sec-fetch-mode":"cors", "sec-fetch-site":"same-origin"
What do they mean? It's like the
Origin
check was already made?For example: if I get
sec-fetch-site: cross-site
it means that the call was generate in another website/domain? Is that correct?Reference:
Sec-Fetch-Site: cross-site Sec-Fetch-Site: same-origin Sec-Fetch-Site: same-site Sec-Fetch-Site: none
-
cbdeveloper about 3 yearsAnd the
sec-fetch
headers are also sent? -
bottomofeverything about 3 yearsYes, they are also sent.
-
danludwig about 3 yearsI'm also seeing this behavior for a web app rendered in an iframe (that has same-origin fetch request), but the method is POST instead of GET. Should it also be omitting the origin header when the method is POST?
-
sideshowbarker about 3 years@danludwig You may want to consider posting a separate question about that. Without seeing a reproducible example stackoverflow.com/help/minimal-reproducible-example with code and the actual request and response headers, all that anybody here can do is just speculate. But per-spec, a POST request from a fetch call should pretty much always have an Origin header, unless no-cors mode has been set for the request.