What is Cross-Site Scripting (XSS)?
Cross-site scripting injects malicious JavaScript into web pages viewed by other users. Learn the three XSS types, what attackers can do with XSS, and how output encoding and CSP prevent it.
Types of XSS
Reflected XSS
Reflected XSS occurs when user-supplied input is immediately returned in the server's response without adequate sanitization. An attacker crafts a URL containing malicious JavaScript, sends it to a victim, and when the victim clicks the link, the malicious script is reflected back from the server and executed in the victim's browser context. The attack requires the victim to click a malicious link, making social engineering a prerequisite.
Stored XSS
Stored XSS — also called persistent XSS — stores malicious scripts in the application's database and serves them to every user who views the affected content. An attacker who injects malicious JavaScript into a comment field, user profile, or other stored content reaches every user who views that content without requiring direct social engineering. Stored XSS in high-traffic applications can affect thousands of users from a single injection.
DOM-Based XSS
DOM-based XSS executes entirely in the browser, without server involvement in the injection. Client-side JavaScript that reads attacker-controlled data from the URL and writes it to the DOM without sanitization creates DOM XSS. Server-side scanning tools may miss DOM XSS because the vulnerability exists in client-side code.
What XSS Enables
Successful XSS allows attackers to execute arbitrary JavaScript in the victim's browser context, providing access to everything the browser can access: session cookies (enabling account takeover), authentication tokens, local storage, browser APIs, and the ability to make authenticated requests to the application on behalf of the victim. XSS that steals session cookies gives attackers access equivalent to the compromised user's account without requiring credentials.
Prevention
Output encoding is the primary XSS prevention: encoding user-supplied data before rendering it in HTML, JavaScript, URL, or CSS contexts converts special characters into safe representations that browsers render as text rather than executing as code. Content Security Policy headers instruct browsers to refuse execution of inline scripts and scripts from unauthorized sources, providing defense-in-depth against XSS even when injection occurs. Modern JavaScript frameworks — React, Angular, Vue — escape output by default, significantly reducing XSS risk in applications built on them — but custom HTML injection and innerHTML usage can re-introduce XSS vulnerabilities even in framework-based applications.
Real-World Example: Samy Worm — XSS at Viral Scale
The Samy worm, created by Samy Kamkar in 2005, exploited a stored XSS vulnerability in MySpace to add Kamkar as a friend and post a message on every visitor's profile. The worm propagated to approximately one million MySpace users in 20 hours — the fastest-spreading computer worm at the time. Each user whose profile the worm reached became a host that would execute the worm code on the next visitor's browser. The attack demonstrated stored XSS's viral propagation potential: a single injection reaches every user who views the affected content, and if those users themselves have profiles that execute the code, the effect compounds geometrically.
Of web applications contain at least one cross-site scripting vulnerability — making XSS the second most common web application vulnerability after SQL injection, and the most common client-side attack enabling account takeover.
.png)