The one-sentence version
The most important security rule in browsers is the Same-Origin Policy: only if the protocol, domain, and port are exactly the same is it considered the "same origin"; pages from different origins cannot read each other's data. Therefore, placing the most sensitive functions on a separate origin is equivalent to building a firewall: even if an XSS vulnerability occurs in another corner of the same website, it cannot reach into this isolated zone. This is a classic practice of "reducing the blast radius" in security engineering.
This article has three layers:
- Layer 1: The Intuition: The same building vs. different buildings
- Layer 2: Real-World Use: Why big companies put user content on different domains
- Layer 3: Principles and engineering key points: The difference between origin and site, and how much isolation is enough
Layer 1: The Intuition
1.1 What is "Same-Origin"
| URL A | URL B | Same Origin? | Reason |
|---|---|---|---|
https://example.com/a |
https://example.com/b |
Yes | Only the path is different |
https://example.com |
http://example.com |
No | Different protocols |
https://example.com |
https://app.example.com |
No | Different domains |
https://example.com |
https://example.com:8443 |
No | Different ports |
Pages with the same origin are like living in the same room: a script in one page can freely read and write the content of another page, send requests, and read localStorage. Pages from different origins live in different rooms and cannot see each other by default.
1.2 Why move out
Suppose a website's login page, blog, forum, and wallet are all under example.com, differing only by path. Then:
- The forum has an XSS vulnerability (e.g., a specific post can embed a script);
- This script runs within the
example.comorigin; - It can read the same-origin wallet page and even secretly change the recipient address on the page.
By moving the wallet to wallet.example.com, the forum's script can no longer touch it. The vulnerability still exists, but it cannot harm the most valuable assets.
Layer 2: Real-World Use
- User content on independent domains: Google puts user-uploaded files on
googleusercontent.com, and GitHub puts user content ongithubusercontent.com. The reason is the same: if a user-uploaded HTML file executes a script, it can only run within an origin that contains "no sensitive data." - Independent admin consoles: Many companies place their administrative backends on a separate domain or even an internal network, completely isolated from the main site facing users.
- Payment pages: Third-party payment forms are usually embedded in merchant pages as iframes, but since the iframe comes from the payment provider's own origin, the merchant page's scripts cannot read the card numbers inside.
- Cryptocurrency: Incidents where wallets and DeFi frontends were tampered with (see "The Bybit Incident and Frontend Integrity") have made people increasingly realize that "the signing page must be a clean, isolated, and auditable origin."
Layer 3: Principles and Engineering
3.1 What the Same-Origin Policy governs
| Action | When Cross-Origin |
|---|---|
| Read the DOM of another window or iframe | Prohibited |
Read responses from fetch / XHR |
Prohibited by default, unless explicitly allowed by the other party via CORS |
| Read localStorage, IndexedDB | Each is independent |
| Sending requests (forms, images, links) | Allowed (this is why CSRF exists; see "Cookie Security Attributes") |
Embedding scripts <script src> |
Allowed, and the script runs as the embedder (see "CSP and SRI") |
3.2 The difference between origin and site
- origin: Protocol + Full Domain + Port.
wallet.example.comandblog.example.comare different origins. - site: Protocol + "Registrable Domain" (eTLD+1). They belong to the same site
example.com.
There are two instances where calculations are based on site rather than origin, meaning subdomain isolation is not perfect:
- Cookies: Brother subdomains can set cookies for
Domain=example.com, affecting your subdomain. The countermeasure is using cookies with the__Host-prefix. - SameSite: A request from
blog.example.comtowallet.example.comis considered "same-site," so SameSite cannot block it. The countermeasure is for the server to verify theOriginheader.
Extremely sensitive applications will simply use a completely different registrable domain, separating even the sites.
3.3 Isolation is not just for the browser
If the frontend moves to a separate origin, the backend must be isolated accordingly; otherwise, it is just changing the address label:
- Independent service processes and system users, independent databases and key files (see "Least Privilege and Key Management");
- Independent sessions that do not share cookies with the main site;
- The frontend is hosted on a platform unrelated to the main site's server: if the main site server is compromised, the attacker also cannot modify this page.
3.4 Stronger isolation headers
| Response Header | Function |
|---|---|
Cross-Origin-Opener-Policy: same-origin |
Prevents other pages from getting a window reference after opening you via window.open |
frame-ancestors 'none' (CSP) |
Prohibits being embedded in an iframe, preventing clickjacking |
Referrer-Policy: no-referrer |
Prevents leaking the current URL (which may contain sensitive parameters) to the other party when navigating away |
Summary
| Layer | Key points |
|---|---|
| Intuition | Same-origin = same room; sensitive functions need their own room |
| Value | The vulnerability remains, but the blast radius is reduced |
| Details | origin ≠ site: cookies and SameSite are calculated by site and require extra handling |
| Complementary | Backend, sessions, and hosting platforms must also be isolated together |