XSStrike: Complete Guide to Advanced Cross-Site Scripting (XSS) Detection and Testing Using Kali Linux

XSStrike: Complete Guide to Advanced Cross-Site Scripting (XSS) Detection and Testing Using Kali Linux

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:

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)

FlagLong formArgumentDescription
-h--helpShow help message and exit
-u--urlURLTarget URL to scan
--dataSTRINGPOST body data to send with each request
-e--encodeurlencode,double,hex,base64Encode generated payloads
--fuzzerflagRun the fuzzing engine instead of the standard scan
--updateflagCheck for and pull the latest version of XSStrike
--timeoutSECONDSHTTP request timeout
--proxyflagRoute traffic through a proxy defined in core/config.py (e.g. Burp on 127.0.0.1:8080)
--paramsflagOnly find/enumerate parameters, don’t test them
--crawlflagCrawl the target site for links, forms, and parameters
--jsonflagTreat --data as a JSON body instead of URL-encoded form data
--pathflagInject payloads into the URL path itself (path-based XSS)
--seedsFILELoad a list of URLs to crawl from a file
-f--fileFILELoad custom payloads from a file instead of the built-in list
-l--levelINTCrawling depth level
--headers"Header: value\nHeader2: value2"Add custom HTTP headers (opens $EDITOR if no value given)
-t(threadcount)INTNumber of concurrent threads
-d(delay)SECONDSDelay between each request (rate limiting)
--skipflagSkip the “would you like to continue” confirmation prompts
--skip-domflagSkip the built-in DOM XSS scan
--blindflagInject the configured blind XSS payload into every form found while crawling
--console-log-leveldebug,info,run,good,warning,error,critical,vulnVerbosity shown on screen
--file-log-levelsame as aboveVerbosity written to the log file
--log-fileFILEPath 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

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

Troubleshooting

ProblemLikely CauseFix
ModuleNotFoundError: No module named 'fuzzywuzzy'Dependencies not installed correctlyRe-run pip3 install -r requirements.txt --break-system-packages
Scan hangs indefinitelyTarget is slow or unreachableAdd --timeout 5 and lower -t
No reflections found on a known-vulnerable parameterInput is being reflected only inside JSON/AJAX response, not the initial HTMLUse --json if testing a JSON API, or manually inspect with --proxy
SSL: CERTIFICATE_VERIFY_FAILEDTarget uses a self-signed/invalid certificateTest against the target via --proxy through Burp with “don’t verify” enabled, or add the cert to your trust store
Crawler misses authenticated pagesNo session cookie suppliedPass --headers "Cookie: SESSIONID=..."
Too many false positivesFuzzer heuristics misjudging reflection context on heavily obfuscated JSManually verify with --proxy and inspect raw response

References

Exit mobile version