What are the three types of XSS and how do they differ?
Stored = payload saved in the DB and served to everyone; Reflected = payload bounced straight back from the request/URL; DOM-based = payload never reaches the server, handled entirely by client-side JS.
* The three XSS types — Stored is saved server-side and served to all; Reflected bounces off the request; DOM-based stays entirely in client-side JS. *
| Type | Where the payload lives | Typical carrier | Executes |
|---|---|---|---|
| Stored XSS (Type I) | Saved server-side, e.g. in the database | message forums, visitor logs, comment fields | Server-side or client-side |
| Reflected XSS (Type II) | Not stored — it rides in the request | error messages, search results, echoed page content | Server-side or client-side |
| DOM-based XSS (Type 0) | Client-side only | a URL fragment read by page JavaScript | Client-side only |
The three names actually mix two independent questions, and separating them is what makes the taxonomy click:
- Does the payload persist? Stored (it waits in the database for every visitor) versus reflected (it must be delivered afresh to each victim, e.g. via a crafted link).
- Where is the untrusted data used? Server-side, when the server pastes it into the HTML it sends; client-side, when page JavaScript writes it into the DOM.
Cross those and you get the four real combinations — stored server XSS, stored client XSS, reflected server XSS, reflected client XSS. DOM-based XSS is a subset of client XSS: the case where the data source is the DOM only (location.href, document.referrer) and it never has to touch the server.
Two consequences worth remembering:
- In reality the three types overlap — a single flaw can be described more than one way, so don't treat the labels as disjoint boxes.
- Stored vs. reflected changes only the likelihood of a successful attack, not the nature of the vulnerability or the most effective defence. Stored is more dangerous because it fires for everyone who loads the page, with no social engineering; reflected needs the victim to follow a link. But the bug is the same bug — untrusted data reaching an output context unencoded — and contextual output encoding fixes all of them.
Go deeper:
Wikipedia — Cross-site scripting — the type taxonomy, notable worms, and the defence history.