Cross-Site Scripting (XSS)
Part of the Cybersecurity Roadmap
In short
If your site prints user input as raw HTML, a stranger's script can run inside your users' browsers, on your domain. The fix is mostly about how you print things.
Injecting malicious JavaScript into a page viewed by other users — stored, reflected, and DOM-based XSS are the three main variants, each exploiting insufficient output encoding.

Think of it like this
The parrot that repeats everything
A pet parrot repeats whatever it hears to every guest. Someone whispers something nasty, and now every visitor hears it. Train the parrot to say "someone told me this" in a flat voice, and it stops causing trouble. Output encoding trains your page the same way.
Watch it happen
A stored comment, safely printed
POST /comments
1/5A comment arrives containing HTML tags. The server can't trust anything a user types.
The big ideas
What you need to know
Three flavours
Stored XSS is saved and shown later. Reflected XSS bounces off a URL. DOM XSS happens inside your own frontend JavaScript.
Encode for the context
HTML body, attributes, URLs and JavaScript need different encoding. Frameworks like React and template engines handle the HTML body for you.
Sanitise allowed HTML
If users may post rich text, pass it through an allowlist sanitiser such as DOMPurify that keeps only safe tags.
Limit the damage
HttpOnly session cookies can't be read by scripts, and a strict CSP blocks scripts you didn't ship.
See it in code
Walk through the code
1// unsafe: builds HTML from user input2// list.innerHTML += `<li>${comment}</li>`;3 4// safe: the browser treats it as plain text5const li = document.createElement("li");6li.textContent = comment;7list.appendChild(li);8 9// server: only allow scripts from your own origin10res.setHeader(11 "Content-Security-Policy",12 "default-src 'self'; script-src 'self'; object-src 'none'"13);1/3innerHTML with user input lets the browser parse it as real markup. That's the root cause of most XSS.
textContent never parses HTML, so tags show up as characters. CSP is the seatbelt for the one place you forgot.
Save yourself the pain
Common mistakes
Oops
Writing your own regex to strip script tags.
Do this instead
Browsers can run code in many ways besides script tags. Use framework encoding, a proven sanitiser and CSP.
Oops
Using dangerouslySetInnerHTML in React because the content "comes from our database".
Do this instead
Data in your database often started as user input. Sanitise it before rendering as HTML.
Your mission
Watch encoding and CSP do their job
Quick check
Your React app renders comments with {comment.text}. Where is XSS still a real risk?
Go deeper
- 1Practice identifying and exploiting XSS in a legal practice lab.
- 2Learn the difference between stored, reflected, and DOM-based XSS.
- 3Understand why proper output encoding (not just input validation) is the real fix.
More topics at this stop
Stuck on this topic? Ask an Insider
Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.