51. Browser security internals: CSP, sandboxing, Spectre, site isolation
Content Security Policy (CSP) is an HTTP response header that
whitelists exactly where scripts/styles/frames/etc. are allowed to load
from — the actual, effective defense against XSS that §47 pointed to,
because even a successful HTML-injection can't execute a <script> tag or
inline handler the policy doesn't permit:
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.trusted.com;
object-src 'none'; base-uri 'self'; frame-ancestors 'none'
default-src 'self' -> only load resources from this same origin by default
script-src ... (no 'unsafe-inline') -> inline <script> tags AND inline event
handlers (onclick="...") are BLOCKED —
this alone defeats the majority of
real-world reflected/stored XSS payloads
object-src 'none' -> blocks <object>/<embed>, a historical plugin-based
XSS vector
frame-ancestors 'none' -> prevents this page from being framed by anyone
(clickjacking defense, replaces the older
X-Frame-Options header)
Renderer sandboxing (§18) restricts what a compromised renderer process
can do at the OS level — Chrome's sandbox on Linux uses seccomp-bpf to
filter which syscalls a renderer can even make, so exploiting a JS engine
bug doesn't automatically grant filesystem/network access; the exploit would
also need a separate sandbox-escape bug.
Spectre (2018) demonstrated that speculative execution — a CPU
performance optimization present in virtually all modern processors — could
be abused to read memory across security boundaries within the same
process via precise timing measurements, defeating purely software-level
isolation like "different JS objects can't see each other's data." Browsers'
actual mitigation wasn't a JS-level patch (the leak is a CPU hardware
behavior, not a JS bug) but process-level isolation: site isolation
(§18) ensures cross-origin data physically lives in a different process
with its own separate memory space, so even a successful Spectre read from
within a malicious page's renderer process cannot reach another origin's
data — it was never mapped into that process's address space at all. This
is also why SharedArrayBuffer/Atomics (§39, which provide the
high-resolution shared-memory timer Spectre-style attacks need) stay
disabled unless a page explicitly opts into cross-origin isolation.