What Is Cross-Site Scripting (XSS)? Types, Examples & Prevention
Cross-site scripting turns a trusted website into a delivery vehicle for the attacker's code, running it in your browser. Here's how XSS works, the three main types, and how to prevent it.
Reviewed & fact-checked against primary sources by the TI News Feed Editorial Team. See our editorial & corrections policy.
Cross-site scripting (XSS) is a web security vulnerability that lets an attacker inject malicious scripts — usually JavaScript — into a legitimate, trusted website, so that the code runs in the browsers of other users who visit it. Because the script executes within the context of the trusted site, it inherits that site's privileges: it can read cookies, steal session tokens, capture keystrokes, modify page content, and act as the victim. XSS is one of the most prevalent web vulnerabilities and a long-standing fixture of the OWASP Top 10.
In short: where SQL injection attacks a site's database, XSS attacks its users — turning a site you trust into the weapon used against you.
How cross-site scripting works
XSS arises when a web application takes data from a user and includes it in a page sent to other users without properly validating or encoding it. If an attacker can get their input reflected back into a page as active code rather than inert text, the browser will execute it. For example, if a comment field or search box echoes input straight into the HTML, an attacker can submit a <script> tag instead of normal text, and every visitor who loads that content runs the attacker's script.
The browser can't tell the attacker's injected script apart from the website's own legitimate code — it all appears to come from the trusted site. That misplaced trust is the heart of the attack.
The three types of XSS
- Stored (persistent) XSS: the malicious script is saved on the target server — in a database, comment, profile, or message — and served to every user who views the affected content. This is the most dangerous type because it can hit many victims automatically without any action on their part.
- Reflected XSS: the script is embedded in a crafted link or request and "reflected" back in the immediate response. The victim must be tricked into clicking the malicious link (often via phishing), at which point the script runs in their browser.
- DOM-based XSS: the vulnerability lives entirely in client-side JavaScript that processes input unsafely, modifying the page's Document Object Model in the browser without the malicious payload necessarily touching the server.
What attackers do with XSS
- Steal session cookies and tokens to hijack a victim's authenticated session — a direct route to account takeover, related to session-cookie theft.
- Harvest credentials by injecting fake login forms or keylogging scripts.
- Perform actions as the victim, such as changing account settings or making transactions.
- Deface pages or redirect users to malicious sites and malware.
- Distribute malware or spread an XSS worm across a platform.
Because XSS runs with the victim's privileges on a trusted site, even a "low-severity" looking flaw can lead to a serious data breach or account compromise.
How to prevent cross-site scripting
- Encode output by context. The core defense is to encode user-supplied data when inserting it into a page, so it's treated as text, not code. Encoding must match the context (HTML, attribute, JavaScript, URL).
- Validate and sanitize input. Allowlist expected formats and sanitize any HTML you must accept (for example, with a vetted sanitizer library for rich text).
- Use a Content Security Policy (CSP). A strong CSP restricts what scripts a page can run, sharply limiting the impact of any injection that slips through.
- Lean on modern frameworks. Frameworks like React, Angular, and Vue auto-escape output by default — but beware of "dangerous" escape hatches that bypass that protection.
- Protect cookies. Mark session cookies
HttpOnlyso scripts can't read them, and useSecureandSameSiteattributes. - Test continuously. Scanners and penetration testing catch XSS flaws as part of vulnerability management.
XSS, SQLi, and the injection family
XSS and SQL injection are the two best-known members of a broader family of injection vulnerabilities, all rooted in the same mistake: mixing untrusted input with trusted code. The lesson generalizes across web security — never trust input, always separate data from executable code, and encode or parameterize at every boundary. Attackers probe for these flaws constantly because they map to high-value techniques in their TTPs, from initial access to credential theft.
XSS in practice: a worked example
Consider a social or support platform that lets users post comments, and that displays those comments to anyone who views the page. If the platform fails to encode what users submit, an attacker can post a "comment" that is actually a script — for instance, one that silently reads each viewer's session cookie and sends it to a server the attacker controls. This is stored XSS: the malicious comment sits in the database, and every visitor who loads the page unknowingly runs the script and leaks their session. The attacker collects those sessions and hijacks accounts one after another, with no victim ever clicking anything unusual. Now layer on the defenses: context-aware output encoding would have rendered the comment as harmless text; a Content Security Policy would have blocked the script from running or from contacting the attacker's server; and marking the session cookie HttpOnly would have stopped the script from reading it at all. Each control independently breaks the attack — which is exactly why defense-in-depth is the right model for XSS. The same example also shows why XSS is rated more seriously than its "just JavaScript" reputation suggests: the ability to run code as the victim, on a site they trust, is a powerful foothold that can cascade into full account takeover.
Where threat intelligence fits
XSS vulnerabilities are widely targeted, and exploit techniques evolve continually. Threat intelligence surfaces which web vulnerabilities and exploitation methods are active, helping security teams prioritize the flaws most likely to be used against their applications and users.
The bottom line
Cross-site scripting injects malicious scripts into trusted websites so they execute in victims' browsers, enabling session hijacking, credential theft, and account takeover. Its three forms — stored, reflected, and DOM-based — all exploit a site's failure to separate user input from executable code. Context-aware output encoding, input sanitization, a strong Content Security Policy, HttpOnly cookies, and modern frameworks are the core defenses. To track the web exploitation techniques in active use, follow our live threat intelligence feed, aggregated from dozens of authoritative sources.
Frequently asked questions
What is cross-site scripting (XSS)?
Cross-site scripting is a web vulnerability that lets an attacker inject malicious scripts into a trusted website so they run in other users' browsers. Because the code executes in the trusted site's context, it can steal cookies and session tokens, capture input, and act as the victim.
What are the three types of XSS?
Stored (persistent) XSS, where the script is saved on the server and served to many users; reflected XSS, where the script is in a crafted link reflected back in the response; and DOM-based XSS, where unsafe client-side JavaScript processes input and modifies the page in the browser.
What is the difference between XSS and SQL injection?
Both are injection attacks, but XSS targets a site's users by running attacker JavaScript in their browsers, while SQL injection targets the site's database by running attacker SQL on the server. They share the same root cause: trusting unvalidated user input.
How do you prevent XSS attacks?
Encode user-supplied output according to its context, validate and sanitize input, deploy a strong Content Security Policy, use modern frameworks that auto-escape output, mark session cookies HttpOnly, and test continuously with scanners and penetration testing.
Why is stored XSS the most dangerous type?
Stored XSS saves the malicious script on the server, so it's automatically served to every user who views the affected content — no clicking required. A single injection can therefore compromise many victims, which makes it more impactful than reflected or DOM-based XSS.
Primary sources & further reading
This guide is reviewed and fact-checked against authoritative primary sources: