IS
All experiments
live

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.

lab note
Why I built it

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.

What I learned

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.

Where it broke

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.

Stack
Reactsandbox iframeCSP

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: vulnerableescapedCSP. The demo lives in an isolated sandbox iframe, so the injection can’t escape it.

live demo· sandbox
Loading demo…

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.