How XSS (Cross-Site Scripting) Works
IntermediateCross-site scripting (XSS) is a vulnerability where an attacker injects malicious JavaScript into a web page that other users view. When the victim browser renders the page, it runs the attacker script as if it came from the trusted site — letting it steal session cookies, capture keystrokes, or perform actions as the user. XSS comes in stored, reflected, and DOM-based forms. The core defence is treating all user data as untrusted: encode it on output and lock down what scripts can run with a Content Security Policy.
Think of a forged note slipped into a trusted newsletter
People trust their company newsletter and act on what it says. If an attacker sneaks a forged instruction into it, readers follow it because it appears to come from a trusted source. XSS is that forged note: the attacker gets their script printed inside a page the victim trusts, so the browser runs it with the site full trust — reading the victim cookies or acting on their behalf. Encoding output is like ensuring anything submitted is printed as plain text, never as an executable instruction.
Step by Step
Key Concepts
Stored vs Reflected vs DOM XSS
Stored XSS saves the payload on the server to affect many users; reflected XSS echoes it back from a single request (usually via a malicious link); DOM-based XSS occurs in client-side JS that inserts untrusted data into the page.
Output Encoding
Converting user data into a safe representation for its context (HTML entities, attribute encoding, JS escaping) so it displays as text rather than being parsed as code. The primary XSS defence.
Content Security Policy (CSP)
A response header that restricts which sources of scripts (and other resources) the browser will execute, so even injected inline scripts are blocked — a strong second layer of defence.
HttpOnly Cookies
A cookie flag that hides the cookie from JavaScript, so an XSS payload cannot read the session cookie via document.cookie — limiting the damage of a successful injection.
Key Facts
- XSS runs in the victim browser with the trusted site privileges, so it can hijack sessions and act as the user — output encoding is the primary fix.
- Modern frameworks (React, Angular, Vue) auto-encode by default, which prevents most XSS — but bypasses like dangerouslySetInnerHTML reintroduce the risk.
- A strong Content Security Policy and HttpOnly session cookies are powerful defence-in-depth layers that limit XSS impact even if encoding is missed somewhere.
Real-World Applications
A comment or profile field
Allowing users to post comments without encoding output lets an attacker store a script that runs for every visitor — the classic stored XSS. Encoding the comment on render neutralises it.
A search results page
Echoing a search term straight into the page enables reflected XSS via a crafted link; encoding the term (which frameworks do by default) ensures it always displays as text.
Frequently Asked Questions
What is cross-site scripting (XSS)?
XSS is a vulnerability where an attacker injects malicious JavaScript into a web page that other users view. When a victim loads the page, their browser executes the injected script as if it came from the trusted site, giving it access to the victim session. The attacker can then steal cookies and tokens, capture input, modify the page, or perform actions as the user. It stems from rendering untrusted user data without proper encoding.
What are the types of XSS?
There are three main types. Stored XSS saves the malicious payload on the server (for example in a comment or profile) so it executes for everyone who views that content. Reflected XSS echoes the payload back from a request, typically delivered via a crafted link that reflects input into the response. DOM-based XSS happens entirely in the browser, when client-side JavaScript writes untrusted data into the page without sanitising it.
How do you prevent XSS?
The primary defence is output encoding: convert user-supplied data into a safe form for the context where it appears (HTML, attribute, or JavaScript) so the browser treats it as text, not code. Modern frameworks do this automatically. Add defence in depth with a Content Security Policy that restricts which scripts can run, set HttpOnly on session cookies so scripts cannot read them, and sanitise any HTML you must render. Avoid unsafe APIs like innerHTML with untrusted data.
What is a Content Security Policy and how does it help against XSS?
A Content Security Policy (CSP) is a response header that tells the browser which sources of scripts, styles, and other resources it is allowed to load and execute. By disallowing inline scripts and restricting scripts to trusted origins, a strong CSP can block injected XSS payloads from running even if an encoding mistake let them into the page. It is a valuable second layer of protection, though it complements rather than replaces proper output encoding.