Cross-site scripting (XSS): script that runs as your site
Cross-site scripting (XSS) is an attack in which a website sends a script written by an attacker to other users' browsers. The browser runs it as if it came from the site, so it can read what the page shows, act as the signed-in user, or change what they see. It happens when user input is placed into a page without being encoded for where it lands.
Quick facts
- Weakness
- CWE-79: improper neutralization of input during web page generation
- OWASP category
- A05:2025 Injection
- Types
- Reflected, stored and DOM-based
- Main fix
- Encode output for the context it lands in; add a Content Security Policy
- Does a WAF stop it?
- Partly. Script and markup in a request are recognisable; DOM-based XSS may never reach the server
How an XSS attack works
A page includes something a user supplied: a search term, a name, a comment. If the page inserts it as markup instead of as text, an attacker can supply markup that contains a script. Every browser that loads the page runs the script with the site's identity.
From there the script can do whatever the page can: read data shown to the user, send requests with their session, change the page to ask for a password. The site's own trust becomes the attacker's tool, which is why XSS on a trusted site is serious even when it looks small.
Reflected, stored and DOM-based XSS
- Reflected XSS. The script travels in the request, usually a link, and the page reflects it straight back. The victim has to open a crafted link.
- Stored XSS. The script is saved, for example in a comment or profile, and served to everyone who views it. No crafted link is needed.
- DOM-based XSS. The page's own JavaScript takes data from the URL or another source and writes it into the page unsafely, so the server may never see the script.
The difference decides who can see the attack. Reflected and stored XSS pass through the server; DOM-based XSS can live entirely in the browser.
XSS and CSRF: what the difference is
Both use the victim's browser, but in opposite directions. XSS runs attacker script inside your site, so it can read and do anything the page can. CSRF makes the victim's browser send a request to your site from somewhere else; it can make requests but cannot read the responses.
An XSS flaw also defeats most CSRF protection, because script running on the site can read the anti-forgery token like the page does.
What a WAF catches, and what it misses
A request filter matches script tags, event handlers and other markup in parameters, and refuses or records them. That covers many reflected and stored attempts, because the script has to arrive in a request at some point.
It misses DOM-based XSS that never reaches the server, payloads encoded or split in ways the rules do not decode, and stored script that arrived through a channel the filter does not read. Fields where users legitimately write markup produce false positives.
How to prevent XSS attacks
- Encode output for its context. HTML body, attribute, JavaScript and URL contexts each need their own encoding; the OWASP XSS Prevention Cheat Sheet lists the rules.
- Use a framework that encodes by default. And treat every place that bypasses it as a review point.
- Avoid writing untrusted data into the page with script. Use APIs that set text, not markup.
- Add a Content Security Policy. A CSP limits which scripts the browser will run, so an injected script is refused even if it gets into the page; see Content Security Policy.
- Mark session cookies HttpOnly. Script cannot read them, which limits what a successful XSS can steal; see session hijacking.
Questions
What is cross-site scripting?
Cross-site scripting (XSS) is an attack in which a website sends a script written by an attacker to other users' browsers, where it runs with the site's identity.
What are the types of XSS?
Reflected XSS, where the script comes in the request and is sent straight back; stored XSS, where it is saved and served to every viewer; and DOM-based XSS, where the page's own script writes untrusted data into the page.
How do you prevent XSS?
Encode output for the context it is inserted into, use a framework that does this by default, avoid writing untrusted data as markup, add a Content Security Policy, and mark session cookies HttpOnly.
What is the difference between XSS and CSRF?
XSS runs attacker script inside your site, so it can read and act. CSRF makes a victim's browser send a request to your site from elsewhere; it can act but cannot read the response.