Chrome's Site Isolation and Firefox's Fission place documents from different sites in different operating-system processes. What attack made a process boundary necessary when the same-origin policy was already enforced in browser code, and what does that boundary protect that in-process checks cannot?
answer
- in-code checks can be speculated past
- cache timing leaks the discarded read
- protection by absence, not by check
- boundary is per-site, not per-origin
- platform default versus application opt-in
basics
~20 sSpectre-class speculative-execution side channels let script read any byte in its own process, regardless of language or same-origin checks. A process boundary is the answer because it removes the foreign data from the address space entirely, rather than relying on code that speculation can bypass.
solid answer
~50 sThe same-origin policy is enforced by checks in the renderer's code, and Spectre-class transient-execution attacks bypass code. Speculative execution runs past a bounds or permission check, touches memory on the mispredicted path, and although the architectural result is discarded, the cache footprint it leaves can be timed — so script can read bytes anywhere in its own address space. That turns "cross-origin data happens to live in this renderer" into "cross-origin data is readable". Site Isolation and Fission respond structurally: documents from different sites — scheme plus registrable domain — get separate renderer processes, cross-site frames become out-of-process frames, and the browser process refuses requests a renderer is not entitled to make. Chrome pairs it with Opaque Response Blocking, which keeps cross-origin HTML, XML and JSON responses from ever entering the wrong renderer. The boundary protects data by absence: what is not in the address space cannot be speculatively read.
go deeper
Know that separate renderer processes per site is a security measure, and that it exists because CPU-level side channels let script read memory that in-code origin checks were supposed to protect.
Explain the mechanism: speculation runs past a check, the mispredicted load leaves a cache trace, timing recovers the value — so the response is to remove the data from the address space rather than add another check.
Show the limits and the complements — per-site rather than per-origin granularity, out-of-process frames, response blocking before delivery, and why an application still opts into cross-origin isolation on top of the platform default.
Own the reasoning that a boundary you cannot afford everywhere is not one you can rely on: weigh subdomain trust, origin-keyed clustering, and whether sensitive surfaces belong on separate registrable domains rather than sibling subdomains.
## The assumption Spectre broke A browser's security boundaries were historically enforced *in code*: the renderer holds documents from several origins, and checks scattered through the DOM and network stack decide which origin may touch which object. That design is sound against a language-level attacker — you cannot reach a JavaScript object you were never handed. Transient-execution attacks changed the attacker model. A modern CPU speculates past branches: it predicts the outcome of a bounds check, executes the load on the predicted path, and rolls back the architectural state if the prediction was wrong. The rollback restores registers and memory, but not the cache. An attacker who can steer the predictor and then time cache access learns which address the speculative path touched — and thereby the value it depended on. The consequence for a browser is blunt: script in a renderer can read bytes anywhere in that renderer's address space, without violating a single line of JavaScript semantics. Every in-code origin check becomes advisory, because the read never goes through the check. ## The structural response If checks cannot be trusted, the data must not be there. That is Site Isolation in Chrome and Fission in Firefox: - Documents from different **sites** are rendered in different OS processes. Site here means scheme plus registrable domain (the eTLD+1), not full origin — `https://a.example.com` and `https://b.example.com` are the same site. - Cross-site `<iframe>` elements become **out-of-process frames**: the frame's document lives in its own renderer, and the browser process composites the result. The frame tree spans processes, which is why this took years to ship. - The **browser process** validates what each renderer asks for. A compromised renderer claiming to be a different site is refused, because site identity is tracked outside the renderer. - Chrome adds **Opaque Response Blocking** (the successor to Cross-Origin Read Blocking): cross-origin responses that look like HTML, XML or JSON and that the requesting context could not legitimately read are not delivered into that renderer at all. Without it, a `no-cors` fetch of a sensitive JSON endpoint would still pull the bytes into the process even though script cannot read them — which under Spectre is enough. The protection is **by absence**. The renderer running attacker script simply does not contain the victim's data, so no side channel can reach it. ## What the boundary does not cover Two limits matter in interviews. **It is per-site, not per-origin.** Two different origins on the same registrable domain may share a process, so a compromised subdomain can sit in the same address space as a sensitive sibling. The opt-in `Origin-Agent-Cluster: ?1` response header requests origin-keyed agent clustering, which browsers may use as a hint toward origin-level separation, but it is a request, not a guarantee. **Resources are finite.** One process per site costs memory, and on constrained mobile devices coverage has historically been narrower than on desktop. A guarantee you cannot pay for everywhere is not a guarantee an application can rely on. ## Why applications still need COOP and COEP A natural objection: if the browser separates processes, why must a page send headers to get `SharedArrayBuffer` back? Because the browser cannot know what *your* document intends. Site Isolation protects site A from site B as a platform default. It does not establish that everything sharing your document's agent cluster consented to be there — a same-site cross-origin frame, a credentialled third-party subresource, or a cross-origin opener can all still be in the picture. `Cross-Origin-Opener-Policy` and `Cross-Origin-Embedder-Policy` are the application's own attestation that nothing unconsenting shares its process, and `crossOriginIsolated` is the browser confirming it. Only against that stronger, application-level statement will the platform hand back the precise timers and shared memory that make a side channel practical to exploit. The two mechanisms are therefore complementary, not redundant: one is a platform default that limits the blast radius of any page, the other is an opt-in that a page earns in exchange for dangerous capabilities. ## How to talk about it An interviewer asking this is usually checking whether you understand *why* a mitigation is architectural rather than a patch. The strong answer names the mechanism (speculative execution plus a cache timing channel), states the invariant it breaks (in-process checks are bypassable), and derives the response (remove the data from the process) — rather than reciting that "Chrome uses multiple processes for security", which was already true before Spectre for stability and exploit-containment reasons.
- Why does the site boundary use registrable domain rather than full origin?Because same-site documents can already reach each other through legacy mechanisms such as `document.domain` and shared cookies, so treating them as one trust unit matched existing behaviour, and one process per origin would multiply memory cost. The gap is real, which is why the `Origin-Agent-Cluster: ?1` header exists to request origin-keyed clustering where an application wants the stricter separation.
- What does Opaque Response Blocking add on top of separating processes?Process separation stops a document from sharing a renderer with another site's *document*, but a page can still issue a no-cors fetch for a cross-origin JSON or HTML endpoint, and those bytes land in its own renderer. Script cannot read them through the API, yet a speculative side channel can. Blocking such responses before delivery keeps them out of the address space entirely.
- If the browser already isolates sites by process, why is SharedArrayBuffer still gated on COOP and COEP?Site Isolation is a platform default about site-versus-site, and it cannot certify what a particular document has embedded or who holds a window reference to it. COOP and COEP are the application asserting that nothing unconsenting shares its agent cluster. Handing back a mechanism that yields nanosecond timing requires that stronger, page-specific statement, not just the default.
saying these in an interview costs you the question
- Saying the same-origin policy already stops Spectre
- Describing Spectre as a browser bug that was patched
- Confusing per-site isolation with per-origin isolation
- Claiming site isolation makes COOP and COEP unnecessary
- Treating multiprocess architecture and site isolation as the same thing