August 15, 2026
A Fast Recon Workflow for Spotting XSS Candidates
A practical pipeline for narrowing thousands of URLs down to the handful worth manually testing for Cross-Site Scripting.

By MD Fahad Hosen
2 min read
- 1 A practical pipeline for narrowing thousands of URLs down to the handful worth manually testing for Cross-Site Scripting.
- 2 Step 1 — Pull Historical URLs and Narrow to Likely Candidates
- 3 Step 2 — Add a Content-Type Filter for Cleaner Signal
- 4 Step 3 — Clean the Output Into a Testable Target List
- 5 Step 4 — Automate Payload Testing
A practical pipeline for narrowing thousands of URLs down to the handful worth manually testing for Cross-Site Scripting.
When you're hunting XSS across a large target, the hardest part isn't running payloads — it's figuring out which endpoints are even worth trying them on. Manually clicking through every parameter on a big scope wastes hours. What actually saves time is a tight pipeline: pull historical URLs, filter down to parameterized ones, check which ones reflect input, and only then start testing payloads.
Below is a workflow I rely on, built entirely from public, well-known recon tools. Nothing here is exotic — the value is in how the pieces are chained together.
Step 1 — Pull Historical URLs and Narrow to Likely Candidates
Passive URL archives (Wayback Machine, Common Crawl, AlienVault OTX, URLScan) hold years of crawled links for a domain, many with query parameters still attached. Grabbing all of them and filtering for parameter patterns typically associated with reflected input gets you a much smaller, higher-signal list.
A typical chain looks like this:
echo target.com | gau | gf xss | uro | Gxss | kxss | tee xss_output.txtecho target.com | gau | gf xss | uro | Gxss | kxss | tee xss_output.txtWhat's happening at each stage:
- gau — pulls historical URLs for the domain from passive sources.
- gf (xss pattern) — filters that list down to URLs whose parameters commonly correlate with XSS (search boxes, redirect params, callback names, etc.).
- uro — dedupes near-identical URLs so you're not re-testing the same endpoint with cosmetic differences.
- Gxss — checks each surviving URL to see if the parameter value is actually reflected back in the response.
- kxss — flags which of those reflected values still contain unfiltered special characters (<, >, ", '), meaning the app isn't sanitizing on the way out.
- tee — writes the results to a file while still showing them in the terminal.
Step 2 — Add a Content-Type Filter for Cleaner Signal
Not every reflected parameter matters — a lot of noise comes from JSON responses, images, or other content types where an XSS payload can't actually execute. Filtering by response content-type before you even check for reflection cuts a lot of dead weight:
echo https://target.com | gau | gf xss | httpx-toolkit -ct -silent -nc | grep -iE "text/html|application/xhtml+xml|application/xml|text/xml|image/svg+xml|application/html|application/xml" | cut -d '[' -f1 | Gxss | kxssecho https://target.com | gau | gf xss | httpx-toolkit -ct -silent -nc | grep -iE "text/html|application/xhtml+xml|application/xml|text/xml|image/svg+xml|application/html|application/xml" | cut -d '[' -f1 | Gxss | kxssThis keeps only responses served as HTML, XHTML, XML, or SVG — the content types where injected markup or script actually has a chance of executing.
Step 3 — Clean the Output Into a Testable Target List
Raw tool output is messy. Strip it down to just the URLs, normalize the parameter values, and dedupe:
cat xss_output.txt | grep -oP '^URL: \K\S+' | sed 's/=.*/=/' | sort -u > final.txtcat xss_output.txt | grep -oP '^URL: \K\S+' | sed 's/=.*/=/' | sort -u > final.txtThis turns something like page.php?id=123 into page.php?id=, then sorts and removes duplicates — leaving a clean list of unique injection points to work through, either manually or with an automated payload runner.
Step 4 — Automate Payload Testing
Once you have a trimmed target list, feeding it into an automated XSS scanner is far faster than testing by hand. Two solid open-source options:
Dalfox can consume the same pipeline output directly:
echo target.com | gau | gf params | uro | Gxss | dalfox pipe --skip-bav --skip-mining-all --skip-grepping --skip-mining-dom --remote-payloads=portswigger,payloadboxecho target.com | gau | gf params | uro | Gxss | dalfox pipe --skip-bav --skip-mining-all --skip-grepping --skip-mining-dom --remote-payloads=portswigger,payloadboxUseful Dalfox variations depending on the situation:
--custom-payload yourfile.txt— swap in your own payload list instead of remote ones.--waf-evasion— automatically slows down requests when it detects WAF-like blocking behavior.--deep-domxss— runs deeper client-side DOM analysis for JavaScript-driven reflection.--blind <collaborator-url>— fires blind XSS payloads that call back to an external listener, useful for admin panels or async-processed input you can't see directly.
loxs is another option built specifically around bulk-testing a target list against a payload file, with an HTML report generated at the end — handy when you need something to attach to a submission.
Wrapping Up
The core idea is simple: don't test payloads against everything — filter aggressively first, so the only URLs you're throwing payloads at are ones that already show reflection and lack sanitization. That alone turns a multi-day manual sweep into something that runs in a couple of minutes and leaves you with a short, high-confidence list to dig into by hand.
This post is for educational purposes. Always test only within the scope and rules of an authorized bug bounty program or an environment you have explicit permission to assess.