Lion Cipher Lab
Stop XSS with output encoding and a Content Security Policy
- AppSec / DevSecOps
- Intermediate
- ~50 min
- Free · no account required
Why it matters
Cross-site scripting is one of the most common and most persistent web vulnerabilities on earth, and almost every real instance of it comes down to the same root cause: someone rendered user-controlled text as if it were trusted markup. Reading that sentence is not the same as feeling it. In this lab you build a tiny web app that has the bug on purpose, then watch three different flavors of XSS — reflected, stored, and DOM-based — actually fire in your own browser using harmless marker payloads. Then you fix each one the right way and watch the fix hold. The reason this matters more than a…
What you'll learn
- standing up a tiny deliberately-vulnerable Flask app on your own machine
- proving reflected, stored, and DOM-based XSS with harmless marker payloads
- telling apart HTML, attribute, JavaScript, and URL contexts and why encoding must match the context
- fixing XSS with contextual output encoding by letting the framework auto-escape (Jinja2)
- recognizing | safe / dangerouslySetInnerHTML / v-html as the loaded footguns they are
- fixing DOM-based XSS with safe sinks (textContent) instead of innerHTML, and sanitizing with DOMPurify when HTML is truly needed
- adding a Content Security Policy with a per-response nonce as defense in depth
- hardening cookies with HttpOnly and SameSite to shrink the blast radius of any XSS that slips through
Steps in this lab
- The words first: XSS, the three types, the DOM, context, encoding
- Set up: Python, Flask, and a folder
- Build the VULNERABLE app (the bugs, on purpose)
- Prove #1 — reflected XSS fires from the URL
- Prove #2 — stored XSS fires for every viewer
- Prove #3 — DOM-based XSS fires without the server
- FIX #1 — contextual output encoding (the primary defense)
- FIX #2 — DOM-based XSS needs a safe SINK, not a server fix
- FIX #3 — a Content Security Policy as defense in depth
- Cookie hardening — shrink the blast radius (it does not prevent XSS)
- Judgment: the hierarchy, the footguns, and how a pro ships