Skip to content
atlas

Cross-site scripting (XSS)

Also known as: XSS

An attack that smuggles a harmful script into a web page, so it runs in the browser of everyone who visits the page.

Draft - this entry has not been reviewed yet.

Formal

A flaw in a web application that places untrusted input into its pages without making it safe first; the web browser then runs that input as code with the same rights as the site's own code, so it can read what the user sees and act in their name.

In plain English

Like a notice board where someone pins up a note that, when read aloud, makes the reader hand over their house keys - the board itself never checks what is pinned to it.

In practice

An attacker posts a comment with a hidden script on a municipality's public consultation page; every resident who opens the page while logged in unknowingly hands the attacker their session.

Why it matters

The harmful code runs inside a site the visitor trusts, so the browser gives it the visitor's session and data; it remains one of the most often reported flaws in web applications.

Technical deep dive

XSS is classified by where the payload lives and where it is turned into code. Reflected XSS echoes input from the current request (a search term, an error parameter) back into the response. Stored XSS persists the payload in the application's data (comments, profile fields, support tickets) and serves it to every viewer, which is why it scales best for the attacker; the 2005 Samy worm on MySpace spread to over a million profiles this way. DOM-based XSS never touches the server's HTML: client-side JavaScript reads an attacker-controlled source such as location.hash or postMessage data and writes it into a dangerous sink such as innerHTML, document.write, eval or a javascript: URL. Mutation XSS (mXSS) exploits the difference between how a sanitizer parses markup and how the browser re-parses it after serialisation.

The root defence is contextual output encoding: the same value needs different escaping in an HTML body, a quoted attribute, a JavaScript string, a CSS value or a URL, and HTML-entity encoding is not sufficient inside a script block or an event-handler attribute. Modern template engines and frameworks (React JSX, Angular, Razor, Thymeleaf) auto-escape by default, so real-world XSS concentrates in escape hatches such as dangerouslySetInnerHTML, bypassSecurityTrustHtml, v-html and raw string templates. When rich HTML must be accepted, it goes through an allowlist sanitizer such as DOMPurify rather than a hand-written regex.

Content Security Policy is the main defence-in-depth layer. A strict CSP uses per-response nonces or hashes with 'strict-dynamic' and disallows inline event handlers, which blocks most injected scripts even when encoding has failed; domain allowlists are routinely bypassed through JSONP endpoints and script gadgets on allowed CDNs. Trusted Types, first shipped in Chromium-based browsers, make DOM sinks reject plain strings, which turns DOM XSS into a type error. HttpOnly cookies stop script from reading the session cookie but do not stop the script from making authenticated requests on the victim's behalf, so they limit rather than prevent the damage.

XSS is catalogued as CWE-79. It was its own OWASP Top 10 category until 2017 (A7), was merged into Injection in 2021 (A03) and remains under Injection as A05 in the 2025 edition. Input validation helps with narrowly typed fields, but it cannot be the primary control, because many legitimate values (names such as O'Brien, free text, markup in a CMS) contain the characters that matter in some output context.

What to learn first

Everything this builds on, foundations first.

  1. Network
  2. →IP address
  3. →Protocol
  4. →Client
  5. →Packet
  6. →Port
  7. →Router
  8. →Server
  9. →TCP/IP
  10. →HTTP
  11. →Internet
  12. →Web application
  13. →Web browser
  14. →Cross-site scripting (XSS)

Relationships

Used with
OWASP Top 10

Sources & further reading

Where this data comes from

This entry was drafted by an AI from the sources above and has not yet been checked by a person. Treat it as a starting point, and check anything important against the sources.

See the review queueSuggest a correction on GitHubThis term as JSON

Mentioned in

Check yourself

Loading…

Atlas is in beta.