XSS playground — how injection breaks a form
Type a “review” with a <script> tag and watch it execute in the vulnerable mode — then see how escaping and CSP shut it down.
At the bank I lock forms down against injection every day, and in interviews I keep seeing that many people “know XSS in theory.” I wanted a demo where injection actually fires — safely, in a sandbox.
The difference between `innerHTML` and `textContent` is literally the difference between having a hole and not having one. And CSP is the second line: even if escaping is forgotten somewhere, a `script-src` without unsafe-inline won’t let the injection run.
The demo itself is a controlled “break.” To make the injection fire for real without touching the main site, I had to move it into an iframe with sandbox and a separate, deliberately weakened CSP.
Three modes of one form
Below is a “review form” rendered three ways. Enter a payload (the button drops in the classic <img onerror>) and switch modes: vulnerable → escaped → CSP. The demo lives in an isolated sandbox iframe, so the injection can’t escape it.
What matters here
CSP mode keeps the vulnerable innerHTML but adds a Content-Security-Policy: script-src 'self' header. Even an inserted script won’t run — the policy blocks inline code. That’s defense in depth: escaping at the input, CSP as insurance.