The Big Picture: Separate Apartments in One Building

You probably have several tabs open at the same time: your email, a bank, a news site and some random page. Your cookies make you logged in to some of them. Now imagine the random page could quietly ask your bank "show me my account" using your cookies, and read the answer. That would be a disaster.

The browser prevents this with one of the most important rules on the web: the Same-Origin Policy (SOP). Think of each website as a separate apartment. Visitors may ring the doorbell (send requests), but they may not walk in and read the papers on the table.

Section 1 showed the process walls (the operating system keeps renderers apart). The SOP is a different wall: a set of rules inside the browser about what web code may read.

6.1 Why It Exists (Security Isolation Between Sites)

What it is: A rule that stops code from one origin from reading data that belongs to another origin.

What is an origin? An origin is three things together:

   https://www.example.com:443/some/page
   └─┬─┘   └──────┬──────┘ └┬┘
  scheme        host      port        origin = scheme + host + port

Two URLs are the same origin only if all three match. The path does not matter.

Compare with https://example.com/aSame origin?Why
https://example.com/b/cYesOnly the path differs
http://example.com/aNoScheme differs (http vs https)
https://www.example.com/aNoHost differs (a sub-domain counts as different)
https://example.com:8443/aNoPort differs (443 is the default for https)
https://example.org/aNoDifferent host

Why it is needed. The browser automatically attaches cookies to requests (Section 5.1). Without the SOP, any page you visit could use your logged-in cookies to read your private mail or bank pages. With it, a page may cause a request, but a page from evil.example cannot read the response from bank.example. Cookies plus SOP are the pair that keeps logged-in sessions safe.

   evil.example page                     bank.example
   ┌────────────────────┐   request    ┌───────────────┐
   │ script: fetch(     │ ──────────►  │ (cookies sent │
   │  "https://bank...")│              │  by browser)  │
   │                    │ ◄──────────  │ response      │
   │ SOP: "You may NOT  │   BLOCKED    └───────────────┘
   │ read this reply."  │ from reading
   └────────────────────┘

6.2 What It Restricts (and What It Allows)

Blocked by default (cross-origin):

BlockedExample
Reading responses to requests (fetch, XMLHttpRequest) to another originA script on a.example cannot read JSON from b.example.
Reading or changing the DOM of a page or frame from another originA page cannot reach into an embedded b.example frame and read its text.
Reading storage of another originlocalStorage, IndexedDB and cookies of b.example are not visible to a.example.

Allowed by default (embedding, not reading): a page can display or run many things from other origins, as long as it cannot read their contents directly:

AllowedExample
Images<img src="https://other.example/pic.png">
Scripts<script src="https://cdn.example/lib.js"> (the script runs with your page's powers, so only include sources you trust)
Stylesheets, fonts, mediaCSS from a CDN, video, audio
Frames<iframe src="..."> (shown, but not readable)
Links and form submitsClicking a link, or a form that posts to another site

This matters: the web would break if sites could not use pictures and libraries from elsewhere. The rule is "you may show it, you may not read it."

Process isolation backs this up. Because Chrome and Edge place different sites in different renderer processes (Section 1.2), even a bug in the browser's SOP checks is harder to exploit. Think of it as the SOP being the rule and site isolation being the lock.

6.3 Opening the Door on Purpose: CORS

Sometimes a site wants another site to read its data (for example a public data service used by many web apps). The server can allow it using CORS (Cross-Origin Resource Sharing): headers in its response.

  Page at https://app.example runs:  fetch("https://api.other.example/data")

  Browser adds:      Origin: https://app.example
  Server answers:    Access-Control-Allow-Origin: https://app.example
  Browser checks:    "Does the allowed origin match mine?"
                      yes -> JavaScript may read the response
                      no / missing header -> blocked, error in Console
HeaderWho sends itMeaning
OriginBrowser (request)"This request comes from this origin." Page scripts cannot fake it.
Access-Control-Allow-OriginServer (response)Which origin may read the answer (a specific origin, or * for anyone, only for non-private data).
Access-Control-Allow-Methods, -HeadersServerWhich methods and extra headers are allowed.
Access-Control-Allow-CredentialsServerWhether cookies may be included. Cannot be combined with *.

Preflight. For "risky" requests (for example a PUT/DELETE, or JSON with custom headers), the browser first sends a small question, an OPTIONS request, before the real one:

 1. Browser ── OPTIONS /data   Origin: https://app.example
                                Access-Control-Request-Method: PUT ──► server
 2. Browser ◄── Access-Control-Allow-Origin: https://app.example
                Access-Control-Allow-Methods: PUT                     ── server
 3. Only if the answer says "yes" does the browser send the real PUT.

You will see these OPTIONS calls in DevTools' Network tab. Two points that surprise beginners:

  • CORS is enforced by the browser, not by the server. A command-line tool is not stopped by CORS. CORS protects the user's browser session, not the server's data from all clients.
  • A "CORS error" in the Console means the server did not give the right permission. You cannot fix it from the page; the server's owner must change its headers.

6.4 Why Cookies and SOP Matter Together

Cookies make requests to a site carry your identity. The SOP stops other sites from reading the replies. But the SOP does not stop another site from sending a request (a form post or image load) to your bank, and the browser may attach cookies. That gap is the opening for CSRF below, which is why the SameSite cookie flag (Section 5.1) exists. Defence comes in layers: SOP, CORS rules, cookie flags, process isolation.

6.5 Two Common Web Attacks, in Simple Words (Defence Only)

We describe these only so you can understand how browsers defend against them.

XSS (Cross-Site Scripting). If a website carelessly shows text that a user typed (for example a comment) without cleaning it, an attacker can type text that is really a script. When other visitors load the page, the script runs inside the trusted site's origin, so the SOP allows it to read that site's data, for example anything JavaScript can see. The attacker's code is now "inside the apartment". Defences: the site must escape (neutralise) user text when displaying it; use a Content Security Policy (a header listing which scripts may run); and mark session cookies HttpOnly so injected scripts cannot read them.

CSRF (Cross-Site Request Forgery). A malicious page tricks your browser into sending a request to another site where you are logged in (for example a hidden form that submits "change my email"). Your cookies go along, so the site may think you asked. The attacker cannot read the reply (SOP), but the action may still happen. Defences: SameSite cookies, secret anti-CSRF tokens in forms that other sites cannot know, and checking the Origin header on the server.

AttackTricks the...Main defence
XSSSite into running attacker text as codeEscape output, CSP, HttpOnly cookies
CSRFBrowser into sending a request with your cookiesSameSite cookies, anti-CSRF tokens

For you as a user: keep the browser updated (security fixes ship often), install few extensions, and do not paste text from strangers into the DevTools Console. Some sites show a warning about this because attackers use it to trick people into running harmful code.

Summary

TermPlain meaning
Originscheme + host + port
Same-Origin PolicyCode from one origin may not read another origin's data
BlockedReading cross-origin responses, DOM and storage
AllowedEmbedding images, scripts, styles, frames, links
CORSServer headers that let chosen origins read its responses
PreflightOPTIONS question before a risky cross-origin request
Access-Control-Allow-OriginWhich origin may read the response
XSSAttacker's script runs inside a trusted site
CSRFAnother site makes your browser send a logged-in request
SameSite / HttpOnly / CSPCookie flag / hide cookie from scripts / script allow-list