You might have come across both “same-site” and “same-origin”, and although they look and sound similar, these terms are among the highly cited but often misunderstood terms. Let us get rid of the confusion by understanding what these terms mean.
According to WHATWG spec, Origins are considered the fundamental currency of the web security model. An origin can be either an opaque origin or a tuple origin.
Opaque origins can be thought of as origins that appear under unusual circumstances. For example, when you open a file locally, the URL would be something like
file:///, in this case, the origin will be an opaque origin, which is null.
Tuple origin is the origin that we all commonly know, as is what everyone is concerned about. A tuple origin consists of
- A scheme (ASCII string)
- A host
- A port (null or 16-bit unsigned integer)
- A domain (null or a domain). Null unless stated otherwise.
The algorithm that decides if two origins (Origin A and Origin B) are of the same origin is:
- If A and B are the same opaque origin, then return true.
- If A and B are both tuple origin and their scheme, hosts, and port are identical, then return true.
- Return false.
This might be a bit confusing as to why we include the domain in the tuple when we already have a host in the tuple. The answer lies in the domain part of the tuple. The domain part of the tuple can be modified using
document.domain setter, though the modern browser has disabled this feature. The tuple is then serialized to obtain a string, which is what we get when we use something like
In simpler terms, this can be understood as – If a website has the same scheme, hostname, and port, it is considered as same-origin; everything else is considered cross-origin. Now let us understand what it means with the help of an example.
|Origin A||Origin B||Result|
Suggested Read: Web Services and Its Attack Types
The site is considered as the combination of TLD, scheme and domain name. So, if we take
http://blog.example.com as an example, the site would be
http://example.com. Now if it is just this much, it is easier to identify site but for TLDs such as
gov.in there is no way to algorithmically figure out the registrable domain which is also known as “eTLD+1”. A registrable domain is a domain formed by the most specific public suffix, along with the domain label immediately preceding it. Now, why do we need something like this? Let us understand with the help of an example. GitHub page is a service that allows anyone to host a static website with a domain like <username>.github.io. Let us say there are two users called Alice and Bob, who both own alice.github.io and bob.github.io, respectively. Now if there was no concept of a public suffix list, both alice.github.io and bob.github.io would be considered as same-site, but GitHub doesn’t want bob.github.io to interfere with alice.github.io, hence they added an entry for github.io in public suffix list, what this means is that the registrable domain of alice.github.io is not github.io but alice.github.io itself and github.io is considered eTLD, which is why both alice.github.io and bob.github.io are not considered a part of the site. Site, in simpler terms, is equivalent to the registrable domain.
“Same site” and “Cross-site” requests
Websites that share the same scheme and the same registrable domain are considered “same-site”, Websites with a different scheme or different registrable domain are considered “cross-site”. Let us understand this with an example.
- A request from
http://dev.example.comis considered the same site because they share the same scheme and registrable domain.
- A request from
http://dev.example.comis considered cross-site because they share different schemes.
- A request from
http://dev.example.orgis considered cross-site because they have a different registrable domain.
It is worth noting that the WHATWG spec was updated to include the scheme as well. Previously, the same site only checked for eTLD+1, which was then updated to introduce a new term in WHATWG spec called schemelessly same-site. Abusing cross-site requests is one of the common web vulnerabilities that can lead to attacks like Cross-Site Web Socket Hijacking (CSWSH).
How to check if a request is “same-origin”, “same-site”, or “cross-site”?
All modern browsers send requests along with the Sec-Fetch-Site HTTP header. The header can only have one of the following values.
- same origin
- same site
You can trust the value of these headers since they are added by browsers and is a forbidden header name, meaning the value of these headers cannot be modified programmatically.
Let us briefly review what we learned.
|Scheme, Hostname and Port must match.||Scheme and eTLD must match.|
|Used in the context of Same-Origin Policy.||Used in the context of cookies.|
|The scheme, Hostname and Port must match.||Domain and port are usually ignored.|