practice

Origin Isolation

also called Sandbox Origin, User Content Origin

Serving user-uploaded or untrusted content from a separate origin, so that content executing there has no access to the application's session, storage or DOM.

frontend-securityxsssame-originuser-contentuploads

The browser's security boundary is the origin — scheme, host and port. Everything sharing an origin shares cookies, storage and scripting access.

An HTML file uploaded by a user and served from the application's own origin therefore executes with the application's full authority: it can read the DOM, call the API as the signed-in user, and read anything in storage. Serving it from a separate origin removes all of that.

Why a different path is not sufficient

Path-based separation is not a security boundary. Same origin means same cookies, same storage, same scripting access, and same-origin requests. Content served under /uploads/ on the application host has every capability that the application has.

This must be a different origin — a distinct host — not a different directory. It is the single most consequential control for any product that stores and serves user files.

Implementation patterns

  • A separate host for user content, ideally a distinct registrable domain so cookie scoping cannot reach it.
  • Content-Disposition and correct content types, so files download rather than render where rendering is not required.
  • X-Content-Type-Options: nosniff, preventing the browser from reinterpreting a file as HTML.
  • A restrictive [[content-security-policy]] on the content origin, and a strict nonce-based policy on the application origin, since that is what limits damage when an injection does occur.
  • Signed time-limited URLs rather than authenticated sessions on the content origin, so the content host never holds a session credential at all.
  • iframe sandboxing where user content must be rendered inline, with the specific capabilities enumerated rather than inherited.

Industry example

File storage, collaboration and design products all reach the same conclusion, usually after a report demonstrating that an uploaded document could exfiltrate a session. The remediation is architectural rather than a patch — a second origin, a change to every content URL, and a review of everything that assumed same origin.

The related lesson is about third-party scripts on the application origin: every included script runs with full origin authority. A tag manager that allows arbitrary script injection is an unmonitored remote code execution path into the authenticated application, and it is usually governed by marketing rather than by engineering.

Failure scenarios

  • User content on the application origin, the root failure.
  • Path-based separation mistaken for isolation.
  • Content type sniffing turning a benign upload into executable HTML.
  • Cookies scoped to a parent domain, which leak to the content subdomain and undo the separation.
  • Inline rendering of user content without sandboxing.

Trade-offs

A second origin costs infrastructure and complicates anything that legitimately needs cross-origin access: CORS configuration, authentication for private files, and preview functionality that wants to render content inline.

Signed URLs solve the authentication problem cleanly and introduce their own considerations — expiry windows, revocation, and the fact that a signed URL is a bearer credential that can be forwarded. Those are far smaller problems than the one origin isolation removes.

Interview question

"Your product lets users upload arbitrary files and share links to them. What is the first architectural decision you make, and what specifically goes wrong if you serve them under a path on your main domain?"