L37 · The Same-Origin Policy

CS 161, Lesson 37, in 50 slides. It covers the browser's core isolation boundary: why the same-origin policy exists, in section 19; what an origin is, namely the scheme, host, and port, in section 19.1; and what the policy restricts against what it allows, which is the difference between reading and embedding, in section 19.2. That same section also gives the exam-critical rules for assigning an origin to scripts, images, and frames, and covers controlled cross-origin communication through postMessage. It is anchored to textbook sections 19.1 to 19.2.

Subject: Computer Security · 81 slides · applied lesson

Open the interactive version of this deck · Homework for this lesson

What this lesson covers

The lesson, slide by slide

1. The Same-Origin Policy

Title

CS 161 · Lesson 37 of 45

The browser's core isolation boundary — why it exists · what an origin is · read vs embed · the script/image/frame origin rules · postMessage

2. By the end of this lesson you can…

Objectives

  1. Explain why the SOP exists: evil.com's JavaScript must not be able to read your Gmail or send mail as you.
  2. Define an origin as the (protocol, domain, port) triple and decide whether two URLs are same-origin by exact string match of all three.
  3. Separate what the SOP restricts (reading another origin's data) from what it allows (embedding cross-origin resources via src).
  4. Apply the origin-assignment rules: a <script> runs with the INCLUDING page's origin; an <img>/<iframe> get the origin they come FROM.
  5. Describe postMessage as the controlled, limited channel for cross-origin communication — and map the SOP to XSS (L40), CSRF (L39), and CORS.

3. What survived from L36 · Web Basics: URLs, HTTP, HTML, the DOM & JavaScript?

Warm-up

Discussion prompt

Before we open L37 · The Same-Origin Policy: without looking back, what was the main idea of L36 · Web Basics: URLs, HTTP, HTML, the DOM & JavaScript, and what could you do by the end of it that you could not do before?

Hint: One sentence for the idea, one for the skill. If the second one is blank, that is the part to revisit.

Answer:

CS 161, Lesson 36, in 57 slides. It covers the browser and protocol model that sits behind every web attack: the parts of a URL in section 18.1, the HTTP request and response model with GET against POST in sections 18.2 to 18.5, the webpage as a distributed application together with HTML and frame isolation in sections 18.6 and 18.7, and CSS, JavaScript, the DOM, and the JavaScript sandbox in sections 18.8 and 18.9. It is anchored to textbook sections 18.1 to 18.9.

4. §19 Why we need the SOP at all

Concept

Concrete scenario: in one tab you have www.gmail.com open and logged in. In another tab you have www.evil.com, a malicious site. Both are running JavaScript in the same browser at the same time.

What you absolutely do NOT want: evil.com's JavaScript reaching over and reading your emails, or sending mail as you. The browser has to keep the two pages apart.

5. Break it if you can: §19 Why we need the SOP at all

Counterexample

Discussion prompt

Concrete scenario: in one tab you have www.gmail.com open and logged in. In another tab you have www.evil.com, a malicious site. Both are running JavaScript in the same browser at the same time.

That is stated as though it always holds. Do one of two things: produce a case where it fails, or say precisely what rules such a case out. "It just does" is not on the menu.

Hint: Hunt at the extremes first — zero, one, negative, empty, equal. If every extreme survives, the reason they survive is the proof.

Answer:

What you absolutely do NOT want: evil.com's JavaScript reaching over and reading your emails, or sending mail as you. The browser has to keep the two pages apart.

6. §19 The browser's answer: isolate everything

Concept

Browsers enforce the same-origin policy (SOP): every webpage is isolated from every other page — EXCEPT when two pages share the same origin. Isolation is the default; sharing is the narrow exception.

Same-Origin Policy (SOP) — A browser rule that isolates each webpage from every other page, so one page's JavaScript cannot read another page's data — unless the two pages have the SAME ORIGIN. Same-origin pages may access each other freely; cross-origin pages are walled off.

7. §19 Same-origin pages trust each other fully

Concept

The flip side of isolation: two pages that DO share an origin get full mutual access. Same-origin JavaScript can read and modify the other page's DOM, see its responses, and use its cookies.

So the SOP is binary at the origin boundary: same origin ⇒ full trust; different origin ⇒ walled off. There is no 'partial' access between two origins by default.

8. By analogy: §19 Same-origin pages trust each other fully

Analogy

Discussion prompt

Explain §19 Same-origin pages trust each other fully by analogy to something with no Computer Security in it at all — a queue, a recipe, a map, a bank balance, whatever fits. Then say where your analogy breaks.

Hint: An analogy that never breaks is not an analogy, it is the same idea wearing a hat. Find the seam — that is the part that is actually new.

Answer:

The flip side of isolation: two pages that DO share an origin get full mutual access. Same-origin JavaScript can read and modify the other page's DOM, see its responses, and use its cookies.

9. §19 Each origin is its own walled apartment

Intuition

Think of the browser as an apartment building. Each origin is a locked apartment. Two pages in the SAME apartment (same origin) can freely walk between rooms and read each other's things.

But your evil.com tab is in a DIFFERENT apartment from your Gmail tab. It cannot walk through the wall to read Gmail's mail. The wall between apartments is the same-origin policy.

Ask yourself: just because two pages are open at once, can one read the other? (No — being open side by side doesn't grant access; only sharing an origin does.)

10. Teach it back: §19 Each origin is its own walled apartment

Explain it

Discussion prompt

Explain §19 Each origin is its own walled apartment to a student a year behind you. No notation, no jargon they have not met — and it still has to be true.

Hint: If your explanation needs a symbol they have never seen, you are describing the notation rather than the idea.

Answer:

Think of the browser as an apartment building. Each origin is a locked apartment. Two pages in the SAME apartment (same origin) can freely walk between rooms and read each other's things.

11. Predict the next row: §19 Trace the threat the SOP defeats

Pattern

Predict first

The table runs: Read the Gmail tab's DOM (your inbox) | BLOCKED | your emails stolen · Read gmail.com's cookies | BLOCKED | your session hijacked

In §19 Trace the threat the SOP defeats, given the rows so far: what is the next one — the row where evil.com's JS attempts is fetch gmail.com and read the reply?

Correct: fetch gmail.com and read the reply | BLOCKED | mail read as you

evil.com's JS attemptswith the SOPwithout the SOP
Read the Gmail tab's DOM (your inbox)BLOCKEDyour emails stolen
Read gmail.com's cookiesBLOCKEDyour session hijacked
fetch gmail.com and read the replyBLOCKEDmail read as you

Why: The relationship between the columns, not the individual numbers, is what generates the next row. Both pages run JavaScript in the same browser process model — the danger is one reaching the other.

12. §19 Trace the threat the SOP defeats

Worked example

evil.com loads in tab 1; gmail.com (logged in) loads in tab 2

Why: Both pages run JavaScript in the same browser process model — the danger is one reaching the other.

evil.com's JS attemptswith the SOPwithout the SOP
Read the Gmail tab's DOM (your inbox)BLOCKEDyour emails stolen
Read gmail.com's cookiesBLOCKEDyour session hijacked
fetch gmail.com and read the replyBLOCKEDmail read as you

Verify: every dangerous read is a CROSS-ORIGIN read, which the SOP blocks

Why: §19: the SOP's job is exactly to block one origin's JS from reading another origin's data. evil.com ≠ gmail.com, so all three attacks are stopped at the origin boundary.

13. Fill in: with the SOP for §19 Trace the threat the SOP defeats

Comparison

Comparison matrix

From §19 Trace the threat the SOP defeats: refill the with the SOP column from what you know. The rest of the table is as it appeared.

evil.com's JS attemptswith the SOPwithout the SOP
Read the Gmail tab's DOM (your inbox)BLOCKEDyour emails stolen
Read gmail.com's cookiesBLOCKEDyour session hijacked
fetch gmail.com and read the replyBLOCKEDmail read as you

14. Something is wrong here: 'an open tab can read another open tab's data by…

Anomaly

Predict first

A student writes this, and it looks reasonable:

A student: 'evil.com and Gmail are both open in my browser, so evil.com's JavaScript can just read what's in the Gmail tab.'

It is wrong. Say what breaks — and say it before you turn the page.

Correct: The same-origin policy ISOLATES them.

A student: when can one page actually read another page's data?

Why: The same-origin policy ISOLATES them. Being open at the same time grants nothing — evil.com (a different origin) cannot read the Gmail tab's DOM, responses, or cookies.

15. Trap: 'an open tab can read another open tab's data by default'

Trap

The trap

A student: 'evil.com and Gmail are both open in my browser, so evil.com's JavaScript can just read what's in the Gmail tab.'

Assume co-resident tabs share access to each other's data

Why: Wrong. The same-origin policy ISOLATES them. Being open at the same time grants nothing — evil.com (a different origin) cannot read the Gmail tab's DOM, responses, or cookies.

The fix

A student: when can one page actually read another page's data?

Only when the two pages share the SAME origin

Why: §19: the SOP isolates every page from every other page by default. Cross-origin reads are blocked; the sole exception is two pages with an identical origin. evil.com ≠ gmail.com, so no access.

16. §19 Isolation is the default, sharing is the exception

Intuition

Notice the design choice: the browser doesn't start with 'everything can talk' and bolt on restrictions. It starts FULLY isolated and carves out one narrow exception — same origin.

That's secure-by-default thinking (L2/L3): deny first, permit deliberately. Every cross-origin interaction has to be explicitly allowed (embedding, postMessage, CORS) rather than assumed.

Ask yourself: if a new browser feature exposes data, what's the safe default? (Cross-origin DENIED — same as the SOP — and let sites opt in if they truly need sharing.)

17. What rests on this: §19 Isolation is the default, sharing is the exception

Socratic

Discussion prompt

Notice the design choice: the browser doesn't start with 'everything can talk' and bolt on restrictions. It starts FULLY isolated and carves out one narrow exception — same origin.

Suppose that were not true. What is the first thing in L37 · The Same-Origin Policy that would stop working?

Hint: Follow it one step downstream. The answer is whatever was quietly relying on it.

Answer:

Ask yourself: if a new browser feature exposes data, what's the safe default? (Cross-origin DENIED — same as the SOP — and let sites opt in if they truly need sharing.)

18. What Is an Origin?

Section

Part 1 · §19.1 protocol + domain + port

19. §19.1 An origin is a triple

Concept

The SOP is defined over origins, so we need an exact definition. An origin is built from three pieces of a URL — and only these three.

Origin — The triple (PROTOCOL, DOMAIN, PORT). Two pages have the same origin only if ALL THREE match exactly (as strings). The path, query, and fragment are NOT part of the origin.

20. Take the definitions apart: Same-Origin Policy (SOP) vs Origin

Definition probe

Sort into buckets

Every line below is part of the definition of Same-Origin Policy (SOP) or of Origin — one or the other, never both. Put each where it belongs.

Same-Origin Policy (SOP)
A browser rule that isolates each webpage from every other page, so one page's JavaScript cannot read another page's data; unless the two pages have the SAME ORIGIN.; Same-origin pages may access each other freely
Origin
The triple (PROTOCOL, DOMAIN, PORT).; Two pages have the same origin only if ALL THREE match exactly (as strings).; The path, query, and fragment are NOT part of the origin.
b1
A browser rule that isolates each webpage from every other page, so one page's JavaScript cannot read another page's data — unless the two pages have the SAME ORIGIN. Same-origin pages may access each other freely; cross-origin pages are walled off.
b2
The triple (PROTOCOL, DOMAIN, PORT). Two pages have the same origin only if ALL THREE match exactly (as strings). The path, query, and fragment are NOT part of the origin.

21. §19.1 Read the origin off the URL

Concept

Take the URL http://wikipedia.org:80/wiki/Cat. Its origin is everything that names WHERE the resource lives — protocol, domain, and port — and nothing about WHICH resource.

http :// wikipedia.org : 80 / wiki/Cat
\__/      \___________/  \_/  \_______/
PROTOCOL     DOMAIN     PORT    path
\_________ origin ________/  (NOT origin)

Same-origin test: line up two URLs and compare protocol, domain, and port. If all three are character-for-character identical, same origin. If any differs, different origin.

22. §19.1 Default ports

Concept

If a URL omits the port, the browser fills in the protocol's default port: 80 for HTTP, 443 for HTTPS. So http://wikipedia.org is treated as http://wikipedia.org:80.

URLeffective port
http://wikipedia.org80 (HTTP default)
http://wikipedia.org:8080 (explicit)
https://wikipedia.org443 (HTTPS default)
http://wikipedia.org:8181 (explicit, NOT default)

So http://wikipedia.org ≡ http://wikipedia.org:80 (same origin), but http://wikipedia.org ≠ http://wikipedia.org:81 — the port differs.

23. What each one costs: §19.1 Default ports

Trade off

Comparison matrix

From §19.1 Default ports: every row here is a choice with a cost. Fill the effective port column, then say which row you would actually pick and what you give up for it.

URLeffective port
http://wikipedia.org80 (HTTP default)
http://wikipedia.org:8080 (explicit)
https://wikipedia.org443 (HTTPS default)
http://wikipedia.org:8181 (explicit, NOT default)

24. §19.1 A subdomain is a different domain

Concept

wikipedia.org and www.wikipedia.org look like 'the same site,' but as origin DOMAIN strings they are not equal — www. makes a different string, hence a different origin.

domain stringcompared to wikipedia.org
wikipedia.orgsame
www.wikipedia.orgDIFFERENT (subdomain prefix)
en.wikipedia.orgDIFFERENT (subdomain prefix)
wikipedia.comDIFFERENT (different TLD)

The same-origin comparison is a literal string match on the host — there is no 'these belong to the same company so they're the same origin' rule.

25. Which is which, by compared to wikipedia.org

Discrimination

Sort into buckets

Sort these by compared to wikipedia.org, from memory, without looking back at §19.1 A subdomain is a different domain. Telling them apart on the spot is the skill; the table is only where the answer happens to be written down.

same
wikipedia.org
DIFFERENT (subdomain prefix)
www.wikipedia.org; en.wikipedia.org
DIFFERENT (different TLD)
wikipedia.com
g1
compared to wikipedia.org is "same" for wikipedia.org — that is what the table on "§19.1 A subdomain is a different domain" records, and it is the single property separating this group from the rest.
g2
compared to wikipedia.org is "DIFFERENT (subdomain prefix)" for www.wikipedia.org, en.wikipedia.org — that is what the table on "§19.1 A subdomain is a different domain" records, and it is the single property separating this group from the rest.
g3
compared to wikipedia.org is "DIFFERENT (different TLD)" for wikipedia.com — that is what the table on "§19.1 A subdomain is a different domain" records, and it is the single property separating this group from the rest.

26. §19.1 All three must match — like a full address

Intuition

An origin is like a full street address: house number AND street AND city. Match the street but not the city and it's a different place. Match domain but not protocol or port, and it's a different origin.

The path is which ROOM you visit once you're at the address — it doesn't change the address. That's why /a/ and /b/ on the same site are the same origin.

Ask yourself: is www.wikipedia.org the same place as wikipedia.org? (No — a different subdomain is a different domain string, so a different origin.)

27. §19.1 Same origin? Decide each pair

Worked example

For each pair, compare PROTOCOL, then DOMAIN, then PORT — all three must match

Why: These are the textbook's canonical examples. We only look at protocol/domain/port; we ignore the path entirely.

URL AURL Bsame origin?why
http://wikipedia.org/a/http://wikipedia.org/b/SAMEpath is NOT part of the origin
http://wikipedia.orghttp://www.wikipedia.orgDIFFERENTdomain differs (subdomain)
http://wikipedia.orghttps://wikipedia.orgDIFFERENTprotocol differs (http vs https)
http://wikipedia.org:81http://wikipedia.org:82DIFFERENTport differs (81 vs 82)

Verify the tricky one: http://wikipedia.org vs http://wikipedia.org:80

Why: §19.1: HTTP's default port is 80, so the first URL's effective port IS 80 — all three parts match, SAME origin. But http://wikipedia.org vs http://wikipedia.org:81 differ in port → DIFFERENT.

28. Draw the shape of it: §19.1 Same origin? Decide each pair

Blank canvas

Draw it

Draw what §19.1 Same origin? Decide each pair just did — the shape of it, not the line-by-line working. One picture, labels only where you need them. Then check it against the steps: anything you could not draw is a step you followed rather than understood.

29. Trap: 'same domain = same origin'

Trap

The trap

A student: 'Both URLs are wikipedia.org, so they're obviously the same origin.'

http://wikipedia.org        vs  https://wikipedia.org   <- protocol differs
http://wikipedia.org        vs  http://www.wikipedia.org <- domain differs
http://wikipedia.org:81     vs  http://wikipedia.org:82  <- port differs

Judge same-origin by the domain alone

Why: Wrong. The origin is (protocol, domain, port) — matching the domain is NOT enough. http vs https differ, a different subdomain (www.) is a different domain string, and different ports differ. Any one mismatch ⇒ different origin.

The fix

A student: what do I actually have to compare?

Compare all THREE: protocol AND domain AND port

Why: §19.1: two pages share an origin only if protocol, domain, and port all match exactly as strings. Same domain with a different scheme, subdomain, or port is a DIFFERENT origin.

30. Inspect it line by line: Trap: 'same domain = same origin'

Error analysis

Annotate

Walk the callouts on Trap: 'same domain = same origin'. Each one is a place this is easy to get subtly wrong.

  • Wrong. The origin is (protocol, domain, port) — matching the domain is NOT enough. http vs https differ, a different subdomain (www.) is a different domain string, and different ports differ. Any one mismatch ⇒ different origin.
  • §19.1: two pages share an origin only if protocol, domain, and port all match exactly as strings. Same domain with a different scheme, subdomain, or port is a DIFFERENT origin.

31. §19.1 Build the origin, then compare

Worked example

Compare https://app.bank.com/login and https://app.bank.com/transfer

Why: Two URLs on the same host — reduce each to its (protocol, domain, port) triple and ignore everything else.

URLprotocoldomainport
https://app.bank.com/loginhttpsapp.bank.com443 (default)
https://app.bank.com/transferhttpsapp.bank.com443 (default)

Verify: all three parts match ⇒ SAME origin (the differing path is ignored)

Why: §19.1: protocol https = https, domain app.bank.com = app.bank.com, port 443 = 443. Identical triples, so same origin — /login and /transfer pages can access each other freely.

32. Fill in: domain for §19.1 Build the origin, then compare

Comparison

Comparison matrix

From §19.1 Build the origin, then compare: refill the domain column from what you know. The rest of the table is as it appeared.

URLprotocoldomainport
https://app.bank.com/loginhttpsapp.bank.com443 (default)
https://app.bank.com/transferhttpsapp.bank.com443 (default)

33. Something is wrong here: 'the path is part of the origin'

Anomaly

Predict first

A student writes this, and it looks reasonable:

A student: 'http://wikipedia.org/a/ and http://wikipedia.org/b/ have different paths, so they're different origins.'

It is wrong. Say what breaks — and say it before you turn the page.

Correct: The path is NOT part of the origin.

A student: which URL parts count for the origin?

Why: The path is NOT part of the origin. Both URLs share the same protocol, domain, and port — so they are the SAME origin and their pages can freely access each other.

34. Trap: 'the path is part of the origin'

Trap

The trap

A student: 'http://wikipedia.org/a/ and http://wikipedia.org/b/ have different paths, so they're different origins.'

Treat /a/ and /b/ as different origins

Why: Wrong. The path is NOT part of the origin. Both URLs share the same protocol, domain, and port — so they are the SAME origin and their pages can freely access each other.

The fix

A student: which URL parts count for the origin?

Only protocol + domain + port — never the path, query, or fragment

Why: §19.1: the origin is read off just three parts. Everything after the host/port (the path and beyond) is ignored when comparing origins. /a/ and /b/ are same-origin.

35. What the SOP Restricts vs Allows

Section

Part 2 · §19.2 read is blocked, embed is allowed

36. §19.2 The SOP blocks cross-origin READS

Concept

Concrete rule: the SOP stops one origin's JavaScript from reading another origin's data — its DOM, the responses to its fetch/XHR requests, and its cookies. evil.com's JS simply cannot read gmail.com's anything.

37. §19.2 …but cross-origin EMBEDDING is allowed

Concept

Crucially, the SOP does NOT stop you from LOADING cross-origin resources. A page may embed images, scripts, and frames from other origins via src. The whole web depends on this — CDNs, ad scripts, embedded videos.

<!-- all allowed on any origin -->
<img    src="https://other.com/logo.jpg">
<script src="https://cdn.com/lib.js"></script>
<iframe src="https://other.com/widget"></iframe>

The line is embed vs read: you may EMBED a cross-origin resource, you just can't READ its contents across the origin boundary.

38. §19.2 Hang the painting, but don't open the safe

Intuition

Embedding a cross-origin image is like hanging a borrowed painting on your wall: you can display it, frame it, size it. That's fine — display is allowed.

Reading across origins is like opening the lender's safe in their house. The SOP locks that. You can show their stuff; you can't reach in and read their private contents.

Ask yourself: does embedding a cross-origin image let your JS read that image's pixels? (No — you can display it, but reading its contents is across the origin boundary, so it's blocked.)

39. §19.2 'Read' covers DOM, responses, and cookies

Concept

When we say the SOP blocks 'reading another origin's data,' that bundles three concrete capabilities an attacker would love — and the SOP denies all three across origins.

cross-origin readwhat it would exposeSOP
another origin's DOMits page contents / form fieldsBLOCKED
its fetch/XHR response bodydata its requests returnBLOCKED
its cookiesits session / login credentialsBLOCKED

40. What rests on this: §19.2 'Read' covers DOM, responses, and cookies

Socratic

Discussion prompt

When we say the SOP blocks 'reading another origin's data,' that bundles three concrete capabilities an attacker would love — and the SOP denies all three across origins.

Suppose that were not true. What is the first thing in L37 · The Same-Origin Policy that would stop working?

Hint: Follow it one step downstream. The answer is whatever was quietly relying on it.

41. Predict the next row: §19.2 Embed (allowed) vs read response (blocked)

Pattern

Predict first

The table runs: Embed google's logo via <img src> | yes | embedding cross-origin is allowed · Display/size that logo on the page | yes | embedding includes layout · JS reads the fetch() response body | NO | reading cross-origin data is blocked

In §19.2 Embed (allowed) vs read response (blocked), given the rows so far: what is the next one — the row where operation is JS reads the embedded image's pixels?

Correct: JS reads the embedded image's pixels | NO | that's reading across origins

operationallowed?why
Embed google's logo via <img src>yesembedding cross-origin is allowed
Display/size that logo on the pageyesembedding includes layout
JS reads the fetch() response bodyNOreading cross-origin data is blocked
JS reads the embedded image's pixelsNOthat's reading across origins

Why: The relationship between the columns, not the individual numbers, is what generates the next row. Two cross-origin operations against google.com — one is embedding, one is reading.

42. §19.2 Embed (allowed) vs read response (blocked)

Worked example

Your page is on http://cs161.org. You want google.com's logo, and you want google.com's homepage HTML

Why: Two cross-origin operations against google.com — one is embedding, one is reading. The SOP treats them very differently.

<!-- on http://cs161.org -->
<img src="http://google.com/logo.jpg">      <!-- embed: OK -->
<script>
  fetch('http://google.com/').then(r => r.text())
</script>                                    <!-- read: BLOCKED -->
operationallowed?why
Embed google's logo via <img src>yesembedding cross-origin is allowed
Display/size that logo on the pageyesembedding includes layout
JS reads the fetch() response bodyNOreading cross-origin data is blocked
JS reads the embedded image's pixelsNOthat's reading across origins

Verify the dividing line: did the resource get LOADED, or did your JS READ its contents?

Why: §19.2: loading/embedding cross-origin is fine; only reading the contents across the origin boundary is blocked. The image renders, but its bytes and the fetch response are off-limits to cs161.org's JS.

43. Which is which, by allowed?

Discrimination

Sort into buckets

Sort these by allowed?, from memory, without looking back at §19.2 Embed (allowed) vs read response (blocked). Telling them apart on the spot is the skill; the table is only where the answer happens to be written down.

yes
Embed google's logo via <img src>; Display/size that logo on the page
NO
JS reads the fetch() response body; JS reads the embedded image's pixels
g1
allowed? is "yes" for Embed google's logo via <img src>, Display/size that logo on the page — that is what the table on "§19.2 Embed (allowed) vs read response…" records, and it is the single property separating this group from the rest.
g2
allowed? is "NO" for JS reads the fetch() response body, JS reads the embedded image's pixels — that is what the table on "§19.2 Embed (allowed) vs read response…" records, and it is the single property separating this group from the rest.

44. Something is wrong here: 'the SOP blocks loading anything from another origin'

Anomaly

Predict first

A student writes this, and it looks reasonable:

A student: 'The SOP isolates origins, so my page can't even load an image or script from another site.'

It is wrong. Say what breaks — and say it before you turn the page.

Correct: The SOP blocks READING cross-origin data, not EMBEDDING cross-origin resources.

A student: what exactly does the SOP forbid?

Why: The SOP blocks READING cross-origin data, not EMBEDDING cross-origin resources. Pages load cross-origin images, scripts, fonts, and frames constantly — that's how CDNs and ads work.

45. Trap: 'the SOP blocks loading anything from another origin'

Trap

The trap

A student: 'The SOP isolates origins, so my page can't even load an image or script from another site.'

Assume the SOP forbids all cross-origin loads

Why: Wrong. The SOP blocks READING cross-origin data, not EMBEDDING cross-origin resources. Pages load cross-origin images, scripts, fonts, and frames constantly — that's how CDNs and ads work.

The fix

A student: what exactly does the SOP forbid?

It blocks READING cross-origin contents; EMBEDDING is allowed

Why: §19.2: you may embed cross-origin resources via src; you just can't read their contents (DOM, responses, cookies) across the boundary. Embed vs read is the whole distinction.

46. §19.2 Why 'embed but not read' is the whole web

Concept

If the SOP blocked all cross-origin loads, there would be no CDNs, no embedded maps, no ad networks, no shared font/script libraries. The web only works because EMBEDDING cross-origin is allowed.

The SOP's design splits the difference: maximize useful sharing (anyone can embed anyone) while denying the one dangerous capability (reading another origin's private contents). Embed freely; read never.

47. The Origin-Assignment Rules

Section

Part 3 · §19.2 scripts, images & frames

48. §19.2 A resource's origin ≠ the URL it came from

Concept

Here's the subtle, exam-critical part. A resource does NOT always get the origin of the URL it was fetched from. Which origin a resource gets depends on the KIND of resource — and the rules differ for scripts, images, and frames.

Getting this wrong is the single most common SOP mistake — and the script rule is exactly what makes XSS (L40) devastating. We'll take the three resource types one at a time.

49. §19.2 JavaScript runs with the INCLUDING page's origin

Concept

Rule 1: JavaScript runs with the origin of the page that LOADS it — not the origin it was downloaded from. A <script src=…> from anywhere runs as if it were part of YOUR page.

<!-- page is on http://cs161.org -->
<script src="http://google.com/tracking.js"></script>
<!-- tracking.js runs with origin cs161.org,
     NOT google.com -->

So that included script has the SAME origin as your page — full access to your DOM, your data, everything. This is why pulling in third-party scripts is dangerous: you're giving their code your origin.

50. §19.2 Images keep the origin they COME FROM

Concept

Rule 2: an image has the origin of where it comes from. An <img src="http://google.com/logo.jpg"> on cs161.org has origin google.com — not cs161.org.

<!-- page is on http://cs161.org -->
<img src="http://google.com/logo.jpg">
<!-- image origin = google.com; cs161.org
     learns only its DIMENSIONS, not pixels -->

Because the image is a different origin, the loading page learns only the image's dimensions (so it can lay out the page) — it cannot read the image's actual pixels.

51. Where does each piece belong: L37 · The Same-Origin Policy

Sorting

Sort into buckets

These are the pieces of L37 · The Same-Origin Policy, out of order. Put each one back under the part of the lesson it belongs to.

What Is an Origin?
§19.1 An origin is a triple; §19.1 Read the origin off the URL; §19.1 Default ports
What the SOP Restricts vs Allows
§19.2 The SOP blocks cross-origin READS; §19.2 …but cross-origin EMBEDDING is allowed; §19.2 Hang the painting, but don't open the safe
The Origin-Assignment Rules
§19.2 A resource's origin ≠ the URL it came from; §19.2 JavaScript runs with the INCLUDING page's origin; §19.2 Images keep the origin they COME FROM
s1
What Is an Origin? is where L37 · The Same-Origin Policy puts §19.1 An origin is a triple, §19.1 Read the origin off the URL, §19.1 Default ports. Knowing which part of the lesson a problem belongs to is most of knowing which method to reach for.
s2
What the SOP Restricts vs Allows is where L37 · The Same-Origin Policy puts §19.2 The SOP blocks cross-origin READS, §19.2 …but cross-origin EMBEDDING is allowed, §19.2 Hang the painting, but don't open the safe. Knowing which part of the lesson a problem belongs to is most of knowing which method to reach for.
s3
The Origin-Assignment Rules is where L37 · The Same-Origin Policy puts §19.2 A resource's origin ≠ the URL it came from, §19.2 JavaScript runs with the INCLUDING page's origin, §19.2 Images keep the origin they COME FROM. Knowing which part of the lesson a problem belongs to is most of knowing which method to reach for.

52. §19.2 Frames get the origin they're RETRIEVED from

Concept

Rule 3: a frame has the origin of the URL the frame is retrieved from. An <iframe src="http://google.com"> on cs161.org has origin google.com — the frame's own URL, not the embedding page's.

<!-- page is on http://cs161.org -->
<iframe src="http://google.com"></iframe>
<!-- frame origin = google.com,
     NOT the embedding page cs161.org -->

So the embedding page (cs161.org) and the framed page (google.com) are DIFFERENT origins, and the SOP walls them off from reading each other — exactly the frame isolation from L36.

53. §19.2 You hire the script; you only display the image

Intuition

Including a <script> is like HIRING a contractor into your house: they walk around with your keys (your origin) and can touch everything. That's why a third-party script is a big trust decision.

Embedding an <img> or <iframe> is like DISPLAYING a borrowed object behind glass: it keeps its own owner (its source origin), and you only see it — you can't reach inside it.

Ask yourself: which of the three resource types gives YOUR page's powers to someone else's code? (The script — it runs with your origin. Images and frames keep theirs.)

54. What rests on this: §19.2 You hire the script; you only display the image

Socratic

Discussion prompt

Including a <script> is like HIRING a contractor into your house: they walk around with your keys (your origin) and can touch everything. That's why a third-party script is a big trust decision.

Suppose that were not true. What is the first thing in L37 · The Same-Origin Policy that would stop working?

Hint: Follow it one step downstream. The answer is whatever was quietly relying on it.

Answer:

Embedding an <img> or <iframe> is like DISPLAYING a borrowed object behind glass: it keeps its own owner (its source origin), and you only see it — you can't reach inside it.

55. §19.2 Three resources, three origins

Worked example

Your page is on http://cs161.org and embeds a script, an image, and an iframe — all from google.com

Why: Same source URL host (google.com) in all three cases. The origin each resource GETS still differs by type.

<!-- all on http://cs161.org -->
<script src="http://google.com/track.js"></script>
<img    src="http://google.com/logo.jpg">
<iframe src="http://google.com"></iframe>
resourceorigin it getswho can access what
<script src=google>cs161.org (the INCLUDING page)runs AS your page — full access to your DOM/data
<img src=google>google.com (where it came from)your page learns only its dimensions, not pixels
<iframe src=google>google.com (the frame's URL)framed page is cross-origin; SOP blocks mutual reads

Verify the danger: the included <script> got YOUR origin, so it can read your whole page

Why: §19.2: scripts run with the including page's origin (cs161.org), images and frames keep google.com. That a script you include runs as YOU is precisely why injecting a <script> (XSS, L40) is so powerful.

56. What each one costs: §19.2 Three resources, three origins

Trade off

Comparison matrix

From §19.2 Three resources, three origins: every row here is a choice with a cost. Fill the origin it gets column, then say which row you would actually pick and what you give up for it.

resourceorigin it getswho can access what
<script src=google>cs161.org (the INCLUDING page)runs AS your page — full access to your DOM/data
<img src=google>google.com (where it came from)your page learns only its dimensions, not pixels
<iframe src=google>google.com (the frame's URL)framed page is cross-origin; SOP blocks mutual reads

57. Trap: 'an included third-party <script> runs with the third party's origin'

Trap

The trap

A student: '<script src="http://google.com/track.js"> is from google.com, so it runs with origin google.com and is isolated from my cs161.org page.'

Give the included script the source URL's origin (google.com)

Why: Wrong. JavaScript runs with the origin of the PAGE THAT INCLUDES it, not where it was downloaded from. track.js runs with origin cs161.org and has FULL access to your page — the opposite of isolated.

The fix

A student: whose origin does an included script actually run with?

The INCLUDING page's origin — your origin

Why: §19.2: an included <script> runs as part of your page with YOUR origin and full access to your DOM and data. This is exactly the mechanism that makes XSS (L40) devastating: injected script runs in the victim page's origin.

58. §19.2 The image leaks shape, not content

Intuition

When cs161.org embeds a google.com image, the browser has to lay out the page, so it must tell cs161.org how big the image is. But size is all it tells — the image's actual pixels belong to google.com's origin.

Think of a wrapped package: you can see its dimensions to fit it on a shelf, but you can't see what's inside. Dimensions leak; contents don't.

Ask yourself: could cs161.org's JS read the colors of an embedded cross-origin photo? (No — that's reading the image's contents across origins, which the SOP blocks; only its dimensions are exposed.)

59. Teach it back: §19.2 The image leaks shape, not content

Explain it

Discussion prompt

Explain §19.2 The image leaks shape, not content to a student a year behind you. No notation, no jargon they have not met — and it still has to be true.

Hint: If your explanation needs a symbol they have never seen, you are describing the notation rather than the idea.

Answer:

Think of a wrapped package: you can see its dimensions to fit it on a shelf, but you can't see what's inside. Dimensions leak; contents don't.

60. Something is wrong here: 'http and https share an origin'

Anomaly

Predict first

A student writes this, and it looks reasonable:

A student: 'http://bank.com and https://bank.com are the same site, so same origin.'

It is wrong. Say what breaks — and say it before you turn the page.

Correct: The protocol is part of the origin.

A student: does switching http→https change the origin?

Why: The protocol is part of the origin. http vs https are DIFFERENT protocols, so http://bank.com and https://bank.com are DIFFERENT origins — even though the domain and (well, ports differ too: 80 vs 443) everything 'looks' like the same site.

61. Trap: 'http and https share an origin'

Trap

The trap

A student: 'http://bank.com and https://bank.com are the same site, so same origin.'

Ignore the protocol when comparing origins

Why: Wrong. The protocol is part of the origin. http vs https are DIFFERENT protocols, so http://bank.com and https://bank.com are DIFFERENT origins — even though the domain and (well, ports differ too: 80 vs 443) everything 'looks' like the same site.

The fix

A student: does switching http→https change the origin?

Yes — different protocol ⇒ different origin

Why: §19.1: the origin is (protocol, domain, port). http and https differ in protocol (and in default port, 80 vs 443), so they are distinct origins and the SOP isolates them from each other.

62. Controlled Cross-Origin Communication

Section

Part 4 · §19.2 postMessage (and ⊕ the rest)

63. §19.2 postMessage: a narrow, opt-in channel

Concept

Sometimes two different-origin pages genuinely need to talk — say an embedded widget and its host. JavaScript's postMessage lets pages of different origins communicate, but with very limited functionality.

postMessage — A JavaScript API that lets two pages of DIFFERENT origins exchange messages in a controlled, limited way. It is not a hole in the SOP: the channel is narrow, and the RECEIVER must validate the sender's origin before trusting a message.

64. §19.2 The receiver must check the origin

Concept

postMessage does not let any origin freely read another's page. It only passes discrete MESSAGES, and the side receiving a message is responsible for verifying who sent it before acting on it.

window.addEventListener('message', (e) => {
  if (e.origin !== 'https://trusted.com') return; // validate!
  handle(e.data);
});

If the receiver skips the e.origin check, any page can send it messages — a real bug. The SOP gives you the sender's origin precisely so you can check it.

65. By analogy: §19.2 The receiver must check the origin

Analogy

Discussion prompt

Explain §19.2 The receiver must check the origin by analogy to something with no Computer Security in it at all — a queue, a recipe, a map, a bank balance, whatever fits. Then say where your analogy breaks.

Hint: An analogy that never breaks is not an analogy, it is the same idea wearing a hat. Find the seam — that is the part that is actually new.

Answer:

If the receiver skips the e.origin check, any page can send it messages — a real bug. The SOP gives you the sender's origin precisely so you can check it.

66. §19.2 A safe vs unsafe postMessage receiver

Worked example

A host page receives messages from an embedded widget at https://trusted.com

Why: Cross-origin by design — the host and widget are different origins, so postMessage is the channel. The question is whether the host trusts blindly.

window.addEventListener('message', (e) => {
  // UNSAFE: no origin check — any page can send this
  handle(e.data);
});
receiver codewho can drive handle()verdict
no e.origin checkANY origin that sends a messageunsafe
if (e.origin !== 'https://trusted.com') return;only trusted.comsafe

Verify: the fix is one line — validate e.origin before acting

Why: §19.2: postMessage hands the receiver the sender's origin precisely so it can check it. Skipping the check turns a controlled channel into an open door for any page.

67. Fill in: who can drive handle() for §19.2 A safe vs unsafe postMessage receiver

Comparison

Comparison matrix

From §19.2 A safe vs unsafe postMessage receiver: refill the who can drive handle() column from what you know. The rest of the table is as it appeared.

receiver codewho can drive handle()verdict
no e.origin checkANY origin that sends a messageunsafe
if (e.origin !== 'https://trusted.com') return;only trusted.comsafe

68. ⊕ Beyond §19: CORS, document.domain, JSONP, DNS rebinding

Concept

⊕ Supplemental — beyond §19.1–19.2. Several other mechanisms relax or attack the SOP; you'll meet them later or in practice, but they're outside this textbook section.

69. §19.2 postMessage is a mail slot, not an open door

Intuition

postMessage is like a mail slot between two locked apartments: you can slide a NOTE through, but you can't walk in and rummage through the other apartment. The wall (the SOP) still stands.

And the note is stamped with the sender's address (e.origin). A careful receiver reads the stamp and ignores notes from addresses it doesn't trust.

Ask yourself: does receiving a postMessage let you read the sender's DOM? (No — you only get the message data, plus the sender's origin to validate. The pages stay isolated.)

70. Break it if you can: §19.2 postMessage is a mail slot, not an open door

Counterexample

Discussion prompt

Ask yourself: does receiving a postMessage let you read the sender's DOM? (No — you only get the message data, plus the sender's origin to validate. The pages stay isolated.)

That is stated as though it always holds. Do one of two things: produce a case where it fails, or say precisely what rules such a case out. "It just does" is not on the menu.

Hint: Hunt at the extremes first — zero, one, negative, empty, equal. If every extreme survives, the reason they survive is the proof.

71. Something is wrong here: 'postMessage lets any origin freely read any other…

Anomaly

Predict first

A student writes this, and it looks reasonable:

A student: 'postMessage is a way around the SOP — once I use it, I can read the other page's whole DOM.'

It is wrong. Say what breaks — and say it before you turn the page.

Correct: postMessage only passes limited MESSAGES between origins — it does not expose the other page's DOM.

A student: what does postMessage actually give you?

Why: postMessage only passes limited MESSAGES between origins — it does not expose the other page's DOM. And the receiver must validate the sender's origin; it isn't an automatic trust channel.

72. Trap: 'postMessage lets any origin freely read any other origin's page'

Trap

The trap

A student: 'postMessage is a way around the SOP — once I use it, I can read the other page's whole DOM.'

Treat postMessage as full cross-origin read access

Why: Wrong. postMessage only passes limited MESSAGES between origins — it does not expose the other page's DOM. And the receiver must validate the sender's origin; it isn't an automatic trust channel.

The fix

A student: what does postMessage actually give you?

A narrow, opt-in message channel — with origin checks required

Why: §19.2: postMessage enables limited cross-origin communication, not arbitrary reads. Each side sends discrete messages, and the receiver is responsible for checking e.origin before trusting the data.

73. Which of these survive contact with L37 · The Same-Origin Policy?

Two truths and a lie

Sort into buckets

Some of these hold up and some are the exact mistakes this lesson is built to prevent. Sort them.

Holds up
What you absolutely do NOT want: evil.com's JavaScript reaching over and reading your emails, or sending mail as you. The browser has to keep the two pages apart.; Ask yourself: just because two pages are open at once, can one read the other? (No — being open side by side doesn't grant access; only sharing an origin does.); Ask yourself: if a new browser feature exposes data, what's the safe default? (Cross-origin DENIED — same as the SOP — and let sites opt in if they truly need sharing.)
Breaks
A student: 'evil.com and Gmail are both open in my browser, so evil.com's JavaScript can just read what's in the Gmail tab.'; A student: 'Both URLs are wikipedia.org, so they're obviously the same origin.'
sound
These are stated as this lesson states them — each one survives the edge cases L37 · The Same-Origin Policy puts it through.
flawed
Each of these is lifted from a trap in this deck: reasonable-sounding, and wrong in a way that only shows up once you rely on it.

74. The same-origin playbook

Pattern

  1. Compute the origin: read off (PROTOCOL, DOMAIN, PORT). Fill defaults — 80 for http, 443 for https. Ignore the path/query/fragment.
  2. Same-origin test: two pages are same-origin only if all THREE parts match exactly as strings. Any difference in protocol, subdomain/domain, or port ⇒ different origin.
  3. Restrict vs allow: the SOP BLOCKS reading cross-origin data (DOM, fetch/XHR responses, cookies) but ALLOWS embedding cross-origin resources (img/script/iframe via src).
  4. Assign the resource's origin: a <script> runs with the INCLUDING page's origin (yours!); an <img> keeps the origin it came from (you get dimensions, not pixels); an <iframe> keeps the origin of the URL it was retrieved from.
  5. Cross-origin talk: use postMessage for limited, opt-in messaging — and ALWAYS validate e.origin on the receiving side.
  6. Map to attacks: 'script runs with the including origin' ⇒ XSS (L40); 'request sent cross-origin but response can't be read' ⇒ CSRF (L39); ⊕ CORS/postMessage are the controlled exceptions.

75. Where does it stop working: The same-origin playbook

Edge cases

Discussion prompt

The same-origin playbook works on the cases you have just seen. Push it to the edge: what is the most degenerate input it still handles — empty, zero, one item, everything equal — and what is the first case where it stops being true? Name the case, not just "it breaks".

Hint: Try the smallest legal input, then the largest, then the one where two things collide. Methods are specified at their edges; the middle takes care of itself.

Answer:

  1. Compute the origin: read off (PROTOCOL, DOMAIN, PORT). Fill defaults — 80 for http, 443 for https. Ignore the path/query/fragment.
  2. Same-origin test: two pages are same-origin only if all THREE parts match exactly as strings. Any difference in protocol, subdomain/domain, or port ⇒…
  3. Restrict vs allow: the SOP BLOCKS reading cross-origin data (DOM, fetch/XHR responses, cookies) but ALLOWS embedding cross-origin resources…
  4. Assign the resource's origin: a <script> runs with the INCLUDING page's origin (yours!); an <img> keeps the origin it came from (you get dimensions…
  5. Cross-origin talk: use postMessage for limited, opt-in messaging — and ALWAYS validate e.origin on the receiving side.
  6. Map to attacks: 'script runs with the including origin' ⇒ XSS (L40); 'request sent cross-origin but response can't be read' ⇒ CSRF (L39); ⊕…

76. Checkpoint — read the origin

Check

A page served from http://cs161.org includes <script src="http://google.com/tracking.js">. Separately, consider whether http://wikipedia.org and https://wikipedia.org are the same origin. Think before choosing.

Check your understanding

Which statement is TRUE?

  • A. tracking.js runs with origin cs161.org (the including page), so it has full access to the cs161.org page's DOM and data. (correct)
  • B. tracking.js runs with origin google.com, so the same-origin policy isolates it from the cs161.org page.
  • C. http://wikipedia.org and https://wikipedia.org are the same origin because they share the same domain.
  • D. http://wikipedia.org/a/ and http://wikipedia.org/b/ are different origins because their paths differ.

Answer: A

Why: §19.2: JavaScript runs with the origin of the page that INCLUDES it, not the origin it was downloaded from. So <script src="http://google.com/tracking.js"> on cs161.org runs with origin cs161.org and has full access to that page's DOM and data — which is exactly why including third-party scripts is dangerous and why XSS (L40) is so powerful. The other claims fail the origin definition (protocol, domain, port; path excluded): http vs https differ in protocol, so they are different origins; and /a/ vs /b/ share protocol+domain+port, so they are the SAME origin.

Why B tempts people
An included script does NOT get the source URL's origin. JavaScript runs with the origin of the INCLUDING page (cs161.org), so tracking.js is NOT isolated — it runs as your page with full access. (Images and frames, by contrast, do keep their source origin.)
Why C tempts people
Same domain is not enough: the origin is (protocol, domain, port). http and https are different protocols (and different default ports, 80 vs 443), so http://wikipedia.org and https://wikipedia.org are DIFFERENT origins.
Why D tempts people
The path is NOT part of the origin. /a/ and /b/ share the same protocol, domain, and port, so they are the SAME origin — the differing path is irrelevant.

77. Misconceptions to retire

Concept

78. Synthesis — the SOP is the web's process isolation

Concept

79. Primary sources & where to read more

Concept

80. Connect it up: L37 · The Same-Origin Policy

Connect it up

Draw it

One page, no notation unless you need it: draw how these connect — What Is an Origin? · What the SOP Restricts vs Allows · The Origin-Assignment Rules · Controlled Cross-Origin Communication. Put an arrow wherever one of them is what makes another possible, and label the arrow with why.

81. Recap — Lesson 37

Recap

You can now say why the SOP exists (keep evil.com out of your Gmail), compute an origin as (protocol, domain, port) and decide same-origin by exact match of all three, separate what the SOP restricts (reading cross-origin data) from what it allows (embedding), apply the script/image/frame origin rules — especially that an included script runs with YOUR origin — and describe postMessage as the controlled cross-origin channel.

Idea§The one-line version
Why the SOP19isolate every page; evil.com must not read Gmail
Origin19.1(protocol, domain, port) — all three must match exactly
Default ports19.180 for http, 443 for https; path is NOT in the origin
Restrict19.2blocks reading cross-origin DOM / responses / cookies
Allow19.2embedding cross-origin img/script/iframe via src is fine
Script origin19.2runs with the INCLUDING page's origin (→ XSS, L40)
Image/frame origin19.2keep the origin they came from (dimensions, not pixels)
postMessage19.2limited cross-origin messaging; receiver checks origin
Bridge—send-but-can't-read ⇒ CSRF (L39); CORS = opt-in exception

Sources

  1. CS 161 Computer Security Textbook §19.1–19.2 — Wagner, Weaver, Kao, Shakir, Law & Ngai, UC Berkeley — why the same-origin policy exists (§19), the definition of an origin as the (protocol, domain, port) triple (§19.1), what the SOP restricts (reading cross-origin data) vs allows (embedding cross-origin resources), the origin-assignment rules for JavaScript / images / frames, and controlled cross-origin communication via postMessage (§19.2)
  2. RFC 6454 — The Web Origin Concept — A. Barth, IETF, December 2011 — the authoritative definition of an origin as the scheme/host/port triple and the principle that the user agent isolates content by origin
  3. WHATWG HTML Standard — Origin — WHATWG — defines origins, same-origin comparison, and the cross-document messaging (postMessage) API
  4. MDN Web Docs — Same-origin policy — Mozilla — readable reference for the same-origin policy, what it blocks vs permits, and cross-origin embedding
  5. W3C — Cross-Origin Resource Sharing (CORS) ⊕ — W3C / WHATWG Fetch Standard — supplemental: how servers opt in to cross-origin reads via Access-Control-Allow-Origin, including simple vs preflighted requests (beyond §19)

Want this taught 1-on-1? Alexander tutors Computer Security — $55/session, free consultation.

Book on Wyzant · Text (657) 465-8108