OWASP

Cross-Site Scripting (XSS): Types, Examples, and How Scanners Find Them

2MNY Admin October 11, 2026 4 min read 8 views

Cross-site scripting lets attackers run their own JavaScript in your visitors' browsers. Here are the three XSS types, the modern DOM-level variants, and how scanners catch them.

Cross-Site Scripting (XSS): Types, Examples, and How Scanners Find Them

Cross-site scripting (XSS) is the most commonly reported vulnerability class in bug bounty programs, and for good reason: when an attacker can execute JavaScript in a victim's browser on your domain, they can steal sessions, impersonate the user, deface content, and pivot into the application's most sensitive features. In this guide we break down the three classic XSS types, the harder DOM-level variants that plain scanners miss, and the detection discipline that keeps false positives out of your reports.

The Three Classic XSS Types

Reflected XSS

The malicious payload travels in the request (typically the URL) and the server echoes it back into the HTML response without encoding. A victim must be tricked into clicking a crafted link — usually via email, chat, or a compromised site. Example: a search page that renders ?q=<script>...</script> directly into the results heading.

Stored XSS

The payload is saved by the application — in a profile field, a comment, a support ticket, a filename — and rendered to every visitor who views that page afterward. Stored XSS is the most dangerous variant because one injection can affect thousands of users, and it persists until the data is cleaned.

DOM-based XSS

The payload never reaches the server. Instead, client-side JavaScript reads attacker-controllable data (often location.hash or location.search) and passes it into a dangerous sink such as innerHTML, document.write, or eval. Because the entire attack happens in the browser, server-side scanners cannot see it — you need a browser engine, or deep static analysis of the JavaScript, to find it.

The Modern Variants That Basic Scanners Miss

Real-world XSS has evolved well beyond <script>alert(1)</script>. A serious scanner needs to understand:

  • DOM clobbering — injecting id/name attributes that shadow global variables and change how the page's own security code behaves (our engine runs a dedicated DOM Clobbering Surface check)
  • postMessage sinks — window.addEventListener('message', ...) handlers that trust arbitrary origins and act on attacker-controlled data (checked by the postMessage Origin Validation scanner)
  • Client-side path taint — URL path fragments flowing into client-side routers and fetch calls that can be redirected
  • JSONP callback hijacking — legacy endpoints that wrap responses in an attacker-chosen callback function, leaking authenticated data cross-origin
  • Prototype pollution — __proto__ injection that poounds JavaScript's inheritance chain and can turn a "harmless" gadget into full XSS (covered both as a dedicated probe and inside the injection-subtechniques scanner)
  • Dangerous token storage — session tokens kept in localStorage, which converts any XSS into immediate account takeover (the Client-Side Token Storage check flags exactly this)

How a Disciplined XSS Scan Works

Detecting XSS reliably is harder than it looks. Naive scanners flag every reflected string as "XSS reflected," which produces reports full of noise. Our approach, layer by layer:

  1. Crawl and collect — the crawler (including a headless Chromium pass for JavaScript-heavy sites) inventories every parameter, form, hash-fragment, and JSONP endpoint.
  2. Context analysis — for each reflection point, determine the context: inside HTML text, an attribute, JavaScript, a URL, or a comment. The payload must match the context or it will never execute.
  3. Payload execution — context-aware payloads probe each point, with the Deep XSS Scanner and dalfox (a dedicated XSS engine) each running their own corpus.
  4. Browser-verified proof — for DOM-based findings, a headless browser confirms the sink actually fires rather than trusting static patterns.
  5. Differential and evidence capture — every confirmed finding stores the exact request, response, and a sanitized proof, so a developer can reproduce it in one step.

Why the Report Matters

An XSS finding is only useful if a developer can act on it immediately. Good reports show the injection point, the payload class, the observed effect, the CWE reference (typically CWE-79), and a concrete fix — output-encode by context (HTML-escaping for text, attribute encoding for attributes, textContent over innerHTML in DOM code), apply a Content-Security-Policy as a second layer, and move session tokens out of JavaScript-accessible storage.

Keep XSS Out of Your Release Cycle

XSS creeps back with every new template, every new endpoint that echoes input, and every new JavaScript dependency. That is why continuous scanning beats one-off audits: catching a reflected parameter the week it ships is dramatically cheaper than discovering stored XSS after an attacker found it first.

Run a free security scan on your site today — the quick tier includes header, cookie, and reflection checks, while deep tiers add the full XSS engine family. You can inspect every one of the 232 scanners on the features page, and developers can self-host our open-source core with 200 modules from GitHub.

Related reading: What Is SQL Injection? · Clickjacking, CORS and CSRF · Security Headers Explained

Frequently Asked Questions
1 What are the three types of XSS?

Reflected XSS (payload travels in the request and bounces back in the response), Stored XSS (payload is saved — in a comment, profile field, or database — and served to every visitor), and DOM-based XSS (the vulnerability lives in client-side JavaScript that writes attacker data into the page, so the malicious change never touches the server). Each needs a slightly different detection approach.

2 How do vulnerability scanners find XSS?

By injecting unique canary strings into every discovered parameter, then checking whether the canary comes back in the HTML in an executable context — inside a script block, an event handler, or a JavaScript sink — accounting for encoding and filter evasion. 2MNY's dalfox-powered module includes hundreds of payload variants and context-aware verification to keep false positives near zero.

3 How do I prevent XSS on my website?

Escape output by context (HTML, attribute, JavaScript, URL — each has different rules), use templating engines that escape by default, add a Content-Security-Policy as a second line of defense, and sanitize rich text with a purpose-built library. Never try to filter input as your only defense — escaping at the point of output is what works.

4 Is XSS still dangerous in 2026?

Very — XSS remains one of the most commonly found critical vulnerabilities because it keeps reappearing in new code, and modern single-page applications moved much of the risk into the DOM where server-side escaping does not reach. It enables session theft, credential capture, and full account takeover.

Is your website affected?

Find out in minutes — free scan, professional report, no credit card.

Start Free Scan