What Is Cross-Site Scripting (XSS)?
Cross-site scripting injects malicious JavaScript into web pages viewed by other users.
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.
Related Reading
What is cross-site scripting (XSS)?
Cross-site scripting is a web application vulnerability that allows attackers to inject malicious JavaScript into pages viewed by other users. When the victim's browser loads the page, the malicious script runs in the context of the legitimate site, gaining access to cookies, session tokens, and the ability to take actions as the user. XSS has been on the OWASP Top 10 for over 20 years and remains common in modern web applications, particularly single-page applications.
What are the main types of XSS?
Reflected XSS injects malicious scripts via URL parameters or form input that the application echoes back without sanitization. Stored XSS persists the malicious script in the application database, executing for every user who views the affected content. DOM-based XSS executes entirely in the browser by manipulating the page's Document Object Model client-side. Stored XSS is generally the most damaging because it requires no special victim interaction beyond visiting a normal page.
How is XSS different from CSRF?
XSS exploits the trust a user's browser has in a website by running attacker-controlled code inside the site context. CSRF exploits the trust a website has in the user's browser by tricking authenticated browsers into submitting requests the user did not intend. Both attack the user, but XSS gives the attacker full code execution in the page context while CSRF gives only the ability to submit specific requests. XSS is generally more dangerous because it enables CSRF and more.
What tools and platforms detect and prevent XSS?
DAST tools including Burp Suite Pro, OWASP ZAP, and Netsparker find XSS through active probing. SAST tools like Checkmarx, Veracode, and Snyk Code identify vulnerable code patterns. Browser-based Content Security Policy headers prevent unsafe inline script execution. Modern frameworks including React, Angular, and Vue auto-escape output by default, significantly reducing XSS risk when used correctly. WAFs from Cloudflare, Akamai, and AWS provide runtime blocking.
How do developers prevent XSS?
Escape all output appropriately for the context where it appears: HTML body, HTML attributes, JavaScript, CSS, and URLs each require different escaping. Use frameworks that auto-escape by default and avoid dangerous patterns like innerHTML or React's dangerouslySetInnerHTML with untrusted data. Implement a strict Content Security Policy that disables inline scripts and limits script sources. Validate input at the boundary and treat all user-controlled data as untrusted regardless of source.
What damage can XSS cause?
Session hijacking through stolen cookies, credential theft through fake login overlays, malware distribution through drive-by download attacks, cryptocurrency theft through clipboard manipulation, and full account takeover when CSRF protections are absent. The 2018 British Airways breach involving Magecart and the 2017 Equifax breach both leveraged XSS-class attacks for skimmer injection. Modern XSS in single-page applications can access local storage, IndexedDB, and modify any client-side behavior.
What is the first step in preventing XSS?
Deploy a Content Security Policy in report-only mode across your applications to discover where unsafe patterns currently exist without breaking functionality. CSP violation reports surface exactly where inline scripts, eval usage, and unsafe content sources live. Use that data to prioritize the cleanup, then move CSP from report-only to enforcement. This single change blocks the majority of XSS exploitability even before code-level fixes are complete.
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.