XSStrike is described by its author as the “most advanced XSS scanner.” It is a Python 3 command-line tool equipped with four hand-written parsers, an intelligent context-aware payload generator, a powerful fuzzing engine, and a fast built-in crawler. Rather than blindly firing a static payload list at every parameter (as older-generation scanners do), XSStrike first analyzes how and where your input is reflected in the response — inside an HTML tag, an attribute, a script block, a JavaScript string, an event handler, etc. — and then constructs a payload specifically tailored to break out of that context and execute JavaScript.
Key capabilities:
- Context analysis — parses the response to determine exact reflection context before generating a payload.
- Intelligent payload generation — crafts the shortest, most reliable payload for the detected context instead of brute-forcing a huge wordlist.
- Powerful fuzzing engine — mutates and tests broken/edge-case payloads to find filter weaknesses.
- WAF detection and fingerprinting — signatures adapted from sqlmap’s WAF detection modules (db/wafSignatures.json).
- Multi-threaded crawler — can crawl a target site and test every discovered form/parameter.
- DOM XSS checking — lightweight static analysis of inline JavaScript for dangerous sinks.
- Blind XSS support — injects a configured blind payload into every form found while crawling.
- GET/POST/JSON support, custom headers, proxy support, payload encoding, and outdated-JS-library detection via an embedded Retire.js-style plugin.
It ships pre-installed on some penetration testing distributions and is easily installed from source on Kali Linux.
Installation
XSStrike requires Python 3. On Kali Linux:
# Update package lists
sudo apt update
# Ensure Python3, pip3 and git are present (usually already on Kali)
sudo apt install -y python3 python3-pip git
# Clone the official repository
git clone https://github.com/s0md3v/XSStrike.git
cd XSStrike
# Install Python dependencies
pip3 install -r requirements.txt --break-system-packages
# Verify installation
python3 xsstrike.py --help
Expected output of the last command (abbreviated):
$ python3 xsstrike.py --help
usage: xsstrike.py [-h] [-u TARGET] [--data PARAMDATA] [-e ENCODE] [--fuzzer]
[--update] [--timeout TIMEOUT] [--proxy] [--params]
[--crawl] [--json] [--path] [--seeds ARGS_SEEDS]
[-f ARGS_FILE] [-l LEVEL] [--headers [ADD_HEADERS]]
[-t THREADCOUNT] [-d DELAY] [--skip] [--skip-dom]
[--blind]
[--console-log-level {debug,info,run,good,warning,error,critical,vuln}]
[--file-log-level {debug,info,run,good,warning,error,critical,vuln}]
[--log-file LOG_FILE]
optional arguments:
-h, --help show this help message and exit
-u TARGET, --url TARGET
target url
--data PARAMDATA post data
-e ENCODE, --encode ENCODE
encode payloads
--fuzzer fuzzer
--update update
--timeout TIMEOUT timeout
--proxy use prox(y|ies)
--params find params
--crawl crawl
--json treat post data as json
--path inject payloads in the path
--seeds ARGS_SEEDS load crawling seeds from a file
-f ARGS_FILE, --file ARGS_FILE
load payloads from a file
-l LEVEL, --level LEVEL
level of crawling
--headers [ADD_HEADERS]
add headers
-t THREADCOUNT number of threads
-d DELAY delay between requests
--skip skip confirmation
--skip-dom skip DOM scanning
--blind inject blind XSS payload
Optional: create a system-wide symlink so the tool can be invoked as xsstrike from anywhere:
chmod +x xsstrike.py
sudo ln -s $(pwd)/xsstrike.py /usr/local/bin/xsstrike
Docker alternative:
docker pull femtopixel/xsstrike
docker run --rm -it femtopixel/xsstrike -u "http://testphp.vulnweb[.]com/listproducts.php?cat=1"
Syntax
python3 xsstrike.py [OPTIONS]
XSStrike does not use subcommands like DalFox; every feature is toggled via a flag combined with -u (single target) or --seeds/--crawl (multiple targets).
General syntax pattern:
python3 xsstrike.py -u "<TARGET_URL>" [--data "<POST_BODY>"] [--crawl] [-l <LEVEL>] \
[--headers "<HEADER: VALUE>"] [--blind] [-t <THREADS>] [-d <DELAY>] [--proxy] \
[--skip] [--skip-dom] [--fuzzer] [-e <ENCODER>] [--timeout <SECONDS>]
Command Line Options (Full Reference)
| Flag | Long form | Argument | Description |
|---|---|---|---|
-h | --help | — | Show help message and exit |
-u | --url | URL | Target URL to scan |
| — | --data | STRING | POST body data to send with each request |
-e | --encode | urlencode,double,hex,base64 | Encode generated payloads |
| — | --fuzzer | flag | Run the fuzzing engine instead of the standard scan |
| — | --update | flag | Check for and pull the latest version of XSStrike |
| — | --timeout | SECONDS | HTTP request timeout |
| — | --proxy | flag | Route traffic through a proxy defined in core/config.py (e.g. Burp on 127.0.0.1:8080) |
| — | --params | flag | Only find/enumerate parameters, don’t test them |
| — | --crawl | flag | Crawl the target site for links, forms, and parameters |
| — | --json | flag | Treat --data as a JSON body instead of URL-encoded form data |
| — | --path | flag | Inject payloads into the URL path itself (path-based XSS) |
| — | --seeds | FILE | Load a list of URLs to crawl from a file |
-f | --file | FILE | Load custom payloads from a file instead of the built-in list |
-l | --level | INT | Crawling depth level |
| — | --headers | "Header: value\nHeader2: value2" | Add custom HTTP headers (opens $EDITOR if no value given) |
-t | (threadcount) | INT | Number of concurrent threads |
-d | (delay) | SECONDS | Delay between each request (rate limiting) |
| — | --skip | flag | Skip the “would you like to continue” confirmation prompts |
| — | --skip-dom | flag | Skip the built-in DOM XSS scan |
| — | --blind | flag | Inject the configured blind XSS payload into every form found while crawling |
| — | --console-log-level | debug,info,run,good,warning,error,critical,vuln | Verbosity shown on screen |
| — | --file-log-level | same as above | Verbosity written to the log file |
| — | --log-file | FILE | Path to write the log file |
Basic Usage (Expected Output)
The simplest possible scan against a single reflected parameter:
python3 xsstrike.py -u "http://testphp.vulnweb[.]com/listproducts.php?cat=1"
Expected terminal output:
XSStrike v3.1.5
[~] Checking for DOM vulnerabilities
[!] WAF Status: Offline
[+] Analysing response
[+] Generating payloads
[!] Reflections found: 3
[~] Analysing reflections
[~] Generating payloads based on context
[!] Payloads generated: 12
[*] Progress: 12/12
[+] WAF Status: Offline
[!] Payload: script>alert()</script>
[!] Efficiency: 100
[!] Confidence: 10
[+] Vulnerable webpage: http://testphp.vulnweb[.]com/listproducts.php?cat=1
[+] Vector for cat: script>alert()</script>
Practical Examples With Output
Example 1 – Scan a single GET parameter
python3 xsstrike.py -u "http://testphp.vulnweb.com/search[.]php?test=query"
[~] Checking for DOM vulnerabilities
[+] Analysing response
[!] Reflections found: 2
[~] Generating payloads based on context
[!] Payload: "svg/onload=alert(1)>
[+] Vulnerable webpage: http://testphp.vulnweb.com/search.php?test=query
[+] Vector for test: "svg/onload=alert(1)>
Example 2 – Test a POST request
python3 xsstrike.py -u "http://target.local/comment[.]php" --data "name=test&comment=hello"
[~] Checking for DOM vulnerabilities
[+] Analysing response
[!] Reflections found: 1
[~] Generating payloads based on context
[!] Payload: 'img src=x onerror=alert(1)>
[+] Vulnerable webpage: http://target[.]local/comment.php
[+] Vector for comment: 'img src=x onerror=alert(1)>
Example 3 – Crawl an entire site at depth 3
python3 xsstrike.py -u "http://testphp.vulnweb[.]com" --crawl -l 3
[~] Crawling the target
[+] Found 14 forms
[~] Testing http://testphp.vulnweb.com/listproducts.php?cat=1
[+] Vulnerable webpage: http://testphp.vulnweb.com/listproducts.php?cat=1
[~] Testing http://testphp.vulnweb.com/search.php?test=query
[!] No reflections found
[~] Testing http://testphp.vulnweb.com/guestbook.php
[+] Vulnerable webpage: http://testphp.vulnweb.com/guestbook.php
[+] Vector for name: "script>alert(1)</script>
Example 4 – Adjust threads and timeout for a slow target
python3 xsstrike.py -u "http://slow-target.local/page.php?q=test" -t 2 --timeout 10
[~] Checking for DOM vulnerabilities
[+] Analysing response
[!] Reflections found: 1
[~] Generating payloads based on context
[*] Progress: 8/8
[!] Payload: script>alert(1)</script>
[+] Vulnerable webpage: http://slow-target.local/page.php?q=test
Example 5 – Add a delay between requests to avoid rate-limiting
python3 xsstrike.py -u "http://target.local/page.php?q=test" -d 2
[~] Checking for DOM vulnerabilities
[+] Analysing response
[*] Progress: 6/6 (delay: 2s between requests)
[!] No reflections found
[+] Not vulnerable
Example 6 – Authenticated scan using custom headers
python3 xsstrike.py -u "http://target.local/profile.php?bio=x" --headers "Cookie: PHPSESSID=abc123; auth=1"
[~] Checking for DOM vulnerabilities
[+] Analysing response
[!] Reflections found: 1
[~] Generating payloads based on context
[!] Payload: onload=alert(document.cookie)>
[+] Vulnerable webpage: http://target.local/profile.php?bio=x
[+] Vector for bio: onload=alert(document.cookie)>
Example 7 – Route traffic through Burp Suite for manual inspection
python3 xsstrike.py -u "http://target.local/page.php?q=test" --proxy
[~] Using proxy 127.0.0.1:8080
[~] Checking for DOM vulnerabilities
[+] Analysing response
[!] Reflections found: 1
[+] Vulnerable webpage: http://target.local/page.php?q=test
Example 8 – Crawl and inject blind XSS payloads into every form
python3 xsstrike.py -u "http://target.local" --crawl --blind
[~] Crawling the target
[+] Found 9 forms
[~] Injecting blind XSS payload into all discovered forms
[+] Blind payload injected: 9/9 forms
[~] Awaiting out-of-band callback on configured blind XSS listener...
Example 9 – Treat POST data as JSON
python3 xsstrike.py -u "http://api.target.local/v1/comment" --data '{"comment":"test"}' --json
[~] Checking for DOM vulnerabilities
[+] Analysing response
[!] Reflections found: 1
[~] Generating payloads based on context
[!] Payload: scriptscript>alert(1)</script>
[+] Vulnerable webpage: http://api.target.local/v1/comment
Example 10 – Run the standalone fuzzer against a parameter
python3 xsstrike.py -u "http://target.local/page.php?q=test" --fuzzer
[~] Fuzzing started
[*] Sent: script>prompt()</script>
[*] Response length: 4523
[*] Response length: 4523
[!] Filter behaviour: tags stripped, no encoding detected
[+] 3 potential filter bypasses discovered, see log for details
Example 11 – Load a custom payload list
python3 xsstrike.py -u "http://target.local/page.php?q=test" -f custom_payloads.txt
[~] Loaded 45 payloads from custom_payloads.txt
[~] Checking for DOM vulnerabilities
[+] Analysing response
[!] Payload: img src=x onerror=alert(document.domain)>
[+] Vulnerable webpage: http://target.local/page.php?q=test
Example 12 – Skip DOM scanning and confirmation prompts for automation
python3 xsstrike.py -u "http://target.local/page.php?q=test" --skip --skip-dom
[~] Skipping confirmation prompts
[~] Skipping DOM XSS scan
[+] Analysing response
[!] Reflections found: 1
[+] Vulnerable webpage: http://target.local/page.php?q=test
Common Use Cases
- Confirming reflected XSS on a single suspicious parameter found during manual testing or Burp Suite passive scanning.
- Crawling and testing an entire small-to-medium web application for reflected/DOM XSS in one pass.
- Validating whether an application’s input filter or WAF can be bypassed (context-aware payload generation + fuzzer).
- Testing authenticated areas of an app by supplying session cookies via
--headers. - Detecting outdated, vulnerable JavaScript libraries loaded by the target (via the built-in Retire.js-derived plugin).
- Injecting blind XSS payloads at scale into every form discovered while crawling, for later correlation with an out-of-band listener (can be paired with XSSHunter, see 8.3).
- Quick sanity-checks of API endpoints that accept JSON bodies.
Automation With Bash
Scan a list of target URLs stored in targets.txt, log full output per host, and collect only confirmed vulnerabilities:
#!/bin/bash
# xsstrike_batch.sh - mass-scan a list of URLs with XSStrike
TARGETS_FILE="targets.txt"
OUTPUT_DIR="xsstrike_results"
mkdir -p "$OUTPUT_DIR"
while IFS= read -r url; do
[ -z "$url" ] && continue
safe_name=$(echo "$url" | sed 's/[^a-zA-Z0-9]/_/g')
echo "[*] Scanning: $url"
python3 xsstrike.py -u "$url" --skip -t 5 --timeout 8 \
--console-log-level info \
--log-file "$OUTPUT_DIR/${safe_name}.log" \
> "$OUTPUT_DIR/${safe_name}.out" 2>&1
if grep -q "Vulnerable webpage" "$OUTPUT_DIR/${safe_name}.out"; then
echo "$url" >> "$OUTPUT_DIR/confirmed_vulnerable.txt"
echo "[+] VULNERABLE: $url"
fi
done < "$TARGETS_FILE"
echo "[*] Done. Confirmed findings in $OUTPUT_DIR/confirmed_vulnerable.txt"
Run it:
chmod +x xsstrike_batch.sh
./xsstrike_batch.sh
Tips and Best Practices
- Always confirm any finding manually in a real browser before reporting — automated scanners (including XSStrike) can produce false positives, especially on heavily templated pages.
- Use
--proxywith Burp Suite or another intercepting proxy to inspect exactly what XSStrike is sending and refine payloads manually when the automated ones fail. - Lower
-t(threads) and add-d(delay) against production or rate-limited targets to avoid tripping WAFs or getting IP-banned. - Combine
--crawlwith-lcarefully — a high crawl level on a large site can generate an enormous number of requests; start at-l 2and increase only if needed. - Use
--blindin combination with an XSSHunter payload (Chapter 8.3) to catch stored/blind XSS that XSStrike’s synchronous scan cannot detect on its own. - Keep the tool updated (
--update) — payload generation logic and WAF signatures are improved frequently. - Always obtain written authorization before scanning any target; XSStrike generates real attack traffic.
Troubleshooting
| Problem | Likely Cause | Fix |
|---|---|---|
ModuleNotFoundError: No module named 'fuzzywuzzy' | Dependencies not installed correctly | Re-run pip3 install -r requirements.txt --break-system-packages |
| Scan hangs indefinitely | Target is slow or unreachable | Add --timeout 5 and lower -t |
| No reflections found on a known-vulnerable parameter | Input is being reflected only inside JSON/AJAX response, not the initial HTML | Use --json if testing a JSON API, or manually inspect with --proxy |
SSL: CERTIFICATE_VERIFY_FAILED | Target uses a self-signed/invalid certificate | Test against the target via --proxy through Burp with “don’t verify” enabled, or add the cert to your trust store |
| Crawler misses authenticated pages | No session cookie supplied | Pass --headers "Cookie: SESSIONID=..." |
| Too many false positives | Fuzzer heuristics misjudging reflection context on heavily obfuscated JS | Manually verify with --proxy and inspect raw response |
References
- Official repository: https://github.com/s0md3v/XSStrike
- Official usage wiki: https://github.com/s0md3v/XSStrike/wiki/Usage
- OWASP Cross-Site Scripting reference: https://owasp.org/www-community/attacks/xss/
