Notes that boss around every reader
Watch it happen
Mallory pins a note with hidden instructions on the public noticeboard. When Alice reads it, her browser follows them and sends her badge to Mallory.
Alice and Mallory walk into the lobby. A public noticeboard lets anyone pin a note, and everyone who walks past can read it. That is how comments, reviews and profiles work.
In bank terms and app terms
| In the bank | In your app |
|---|---|
<script> tag or event handler placed in user input | |
Are you exposed?
You use dangerouslySetInnerHTML,innerHTML,v-htmlordocument.writewith anything a user typed.Your search page or error message repeats the user’s text back inside the HTML. You store the login token in localStorage, where any injected script can read it.
Show user text as text. Let React, Vue or your template engine escape it, and avoid raw HTML insertion. If you must allow HTML (rich text), clean it with a sanitizer library such as DOMPurify. Add a Content-Security-Policy header as a second layer, and keep session cookies HttpOnlyso scripts cannot read them. That limits theft, but injected script can still act as the user.
It has happened to real companies
British Airways (2018) — Attackers who got into British Airways' systems through a compromised contractor account planted a card skimmer on its payment page. British Airways said at the time that up to 380,000 card payments were affected. The UK data regulator (ICO) fined it £20 million in 2020, after finding that basic protections such as multi-factor authentication were not in place. Script skimming like this is the kind of attack that a strict Content Security Policy and careful control of the scripts on a payment page are meant to make harder.
eBay (2016) — Researchers at Check Point showed that eBay's filter for listing descriptions could be bypassed to run JavaScript from a listing. In February 2016 Netcraft reported criminals using it: listings on hijacked seller accounts redirected visitors to fake eBay pages, including a fake login page that harvested usernames and passwords.
What it looks like in code
// BAD: User input reflected directly in HTML
export async function GET(request: Request) {
const query = new URL(request.url).searchParams.get("q")
return new Response(`<h1>Results for: ${query}</h1>`, {
headers: { "Content-Type": "text/html" }
})
}
// BAD: React dangerouslySetInnerHTML with user data
function Comment({ text }) {
return <div dangerouslySetInnerHTML={{ __html: text }} />
}
Ask your AI tool to fix it
Paste this into Cursor, Claude, Lovable, Bolt or whatever you build with.
Find every place the frontend or server renders user-controlled content as HTML (innerHTML, dangerouslySetInnerHTML, v-html, document.write, unescaped template output). Replace with safe text rendering, or sanitize with DOMPurify where rich text is required. Add a strict Content-Security-Policy header and make session cookies HttpOnly, Secure and SameSite. List the changes.Where this comes from
The facts, figures and fixes on this page were checked against these sources on 25 Oct 2026. They are linked so you can check for yourself.
- Cross Site Scripting Prevention Cheat SheetOWASPOutput escaping, React's dangerouslySetInnerHTML caveat, sanitizing rich text with DOMPurify
- HTML5 Security Cheat SheetOWASPDon't keep session tokens in localStorage; HttpOnly cookies reduce the risk
- Content Security Policy (CSP)MDN Web DocsContent-Security-Policy header as a second layer of defense against XSS
- British Airways fined £20m over data breachBBC NewsICO £20m fine in 2020; multi-factor authentication was not in place
- British Airways, Another Victim of Ongoing Magecart AttacksSecurityWeek2018 British Airways breach was a web card skimmer; BA's 380,000 figure
- Partially Fixed eBay Flaw Exploited for Phishing, ScamsSecurityWeekCheck Point's eBay filter bypass; Netcraft saw it used for fake eBay login pages (Feb 2016)
Spot a mistake or something out of date? Report a correction · How these guides are made and checked
The free, open-source scanner checks for most of the problems in these guides.