Lion Cipher Lab

Serve user-uploaded files safely: a separate origin, Content-Disposition, nosniff and a sandbox CSP

Why it matters

Accepting an upload safely is only half the job. The other half is what happens when someone OPENS that file later. If your app serves a user's file from its own origin and lets the browser treat it as a web page, a file someone uploaded can run script with your app's privileges: read the page, act as the logged-in user, and call your API. That is stored cross-site scripting delivered as an attachment, and it does not need a bug in your HTML templates at all. An .html file, an .svg with a script tag, or a file with no type at all whose bytes look like HTML is enough. Big platforms answered…

What you'll learn

Steps in this lab

  1. The problem, and the words you need
  2. Why serious platforms move user files to another domain
  3. Set up: check Python and make a folder
  4. Build the two serving styles in one server
  5. What each hardened header tells the browser
  6. Build the header audit (the browser rules, written as code)
  7. Run it and read the headers
  8. Measure it: which files would run script in your app's origin
  9. Take the layers away one at a time
  10. The cookie check: a separate origin is not a separate site
  11. Confirm it in a real browser with DevTools
  12. What this design does NOT do, and how a pro goes further

Open the full interactive lab →