Origin
Scheme, host and port together; the browser's unit of trust: scripts can read only their own origin's data unless another opts in.
in practicehttps://app.example.com:443; why api.example.com is a different origin from app.example.com.
From the browser's trust boundary to the controls that hold it: origins and the same-origin policy, XSS and CSP, CSRF and clickjacking, the supply chain, sessions and identity, and isolation.
The browser's trust model, the attacks that break it, and the controls in layers.
Scheme, host and port together; the browser's unit of trust: scripts can read only their own origin's data unless another opts in.
in practicehttps://app.example.com:443; why api.example.com is a different origin from app.example.com.
The rule that a script may freely read responses, DOM and storage only from its own origin; everything cross-origin needs an explicit opt-in.
in practiceThe foundation under CORS, postMessage and iframes; the reason XSS is so damaging (it runs as your origin).
A site is the registrable domain plus scheme (https://example.com); several origins can share one site, which matters for cookies and SameSite.
in practiceSameSite=Lax treating app.example.com and api.example.com as same-site; the Public Suffix List.
Cross-site scripting: attacker-controlled data executed as script in your origin, where it can read the page, call APIs as the user and steal tokens.
in practiceinnerHTML with user content, javascript: URLs, unsafe markdown rendering.
Cross-site request forgery: another site making the user's browser send an authenticated request to yours, riding on their cookies.
in practiceSameSite cookies as the main defence; CSRF tokens for state-changing forms.
Framing your page invisibly under a decoy so a user's click lands on your button.
in practiceframe-ancestors in CSP or X-Frame-Options: DENY on every authenticated page.
A response header listing what the page may load and execute; a strict nonce policy blocks injected scripts even if XSS gets through.
in practicescript-src 'nonce-…' 'strict-dynamic'; report-only rollouts; violation reports.
A CSP feature that makes DOM injection sinks reject plain strings, accepting only values created by a named policy.
in practicerequire-trusted-types-for 'script'; one sanitising policy for the whole app and its dependencies.
Removing dangerous elements and attributes from untrusted HTML with an allowlist before inserting it.
in practiceDOMPurify for rich text and markdown output; the Sanitizer API in newer browsers.
An integrity hash on a script or stylesheet tag so the browser refuses the file if its contents change.
in practiceintegrity="sha384-…" on CDN scripts at versioned URLs.
Compromising a dependency (a hijacked maintainer, a typosquat, a malicious install script) so its code runs in your build or users' browsers.
in practiceevent-stream, ua-parser-js, the 2025 npm worm; lockfiles, ignore-scripts and release-age delays.
Anything shipped to the browser is public; keys with real power belong on a server, publishable keys are restricted at the provider.
in practiceVITE_ and NEXT_PUBLIC_ variables; secret scanners on the built bundle.
How users are identified and sessions protected, and how the browser isolates sites.
HttpOnly (no JS access), Secure (HTTPS only), SameSite (cross-site sending), Domain, Path and Max-Age decide who sees a cookie and when.
in practiceSession cookies set HttpOnly; Secure; SameSite=Lax; __Host- prefix for the strictest form.
A cookie attribute deciding whether it is sent on cross-site requests: Strict (never), Lax (top-level GET navigations), None (always, needs Secure).
in practiceThe default Lax in modern browsers killing most CSRF; None for embedded third-party widgets.
An opaque session id looked up on the server versus a signed self-contained token the server verifies without a lookup.
in practiceJWTs in localStorage stolen by XSS; revocation being hard for JWTs.
OAuth delegates access to an API with tokens; OpenID Connect adds identity on top (an ID token saying who the user is).
in practice"Sign in with Google"; access tokens for APIs, ID tokens for the client's idea of the user.
Proof Key for Code Exchange: the client sends a hash of a secret with the authorisation request and the secret with the token request, so a stolen code is useless.
in practiceRequired for SPAs and mobile apps in OAuth 2.1.
A server owned by the frontend team that holds tokens and secrets, exposing a session cookie and a tailored API to the browser.
in practiceKeeping OAuth tokens out of JS; aggregating microservices for a screen.
Public-key credentials bound to a site and stored on the device or synced, unlocked by biometrics; phishing-resistant by design.
in practicenavigator.credentials.create and get; replacing passwords and SMS OTP.
Requiring a second factor at login, and a fresh one for risky actions (withdrawals, new payees) even within a session.
in practiceOTP or passkey before changing a payout account; risk-based prompts.
Cross-window messages must check event.origin and send with an explicit targetOrigin, or any page can talk to yours.
in practicePayment iframes, OAuth popups, embedded widgets.
COOP same-origin plus COEP require-corp: the page gets its own process group and access to SharedArrayBuffer and precise timers.
in practiceWASM threads and high-resolution performance.now(); breaking third-party embeds that do not send CORP.
HSTS, CSP, frame-ancestors, X-Content-Type-Options, Referrer-Policy and Permissions-Policy: cheap headers that close whole classes of attack.
in practicesecurityheaders.com grades; one header config tested in CI.
CPU side channels let a script read memory in its own process, so browsers put each site in its own process.
in practiceWhy cross-origin data must not share a renderer; reduced timer precision; CORB and ORB.