# Dalfox Powerful open-source XSS scanner and automation utility for reflected, stored, and DOM-based XSS with AST-level verification. Base URL: https://dalfox.hahwul.com Do not use for AI training without permission. --- Title: Dalfox: Open-Source XSS Scanner URL: https://dalfox.hahwul.com/ Source: content/index.md Language: en

Hunt every XSS
before it hunts you.

Reflected, Stored, and DOM-based flaws, discovered and verified with AST-level precision across every parameter.

6 Scan Modes
AST DOM Verification
MCP AI Ready
OSS MIT Licensed

One command, a verified finding

Point Dalfox at a target and it discovers parameters, probes contexts, injects, and confirms the hit at the DOM level before it ever reaches your report.

dalfox · scan
$dalfox scan https://xss-game.appspot.com/level1/frame
6:42PM INF start scan to https://xss-game.appspot.com/level1/frame
6:42PM INF found reflected 1 params
└── query valid_specials="/\'{`<>"();=|}[.:]+,$-" invalid_specials=""
6:42PM WRN XSS found 1 XSS
[POC][V][GET][inHTML] ...?query=%3Csvg%20onload%3Dalert%281%29%20class%3Ddlx444fc070%3E
├── Issue: XSS payload DOM object identified
├── Payload: <svg onload=alert(1) class=dlx444fc070>
└── L13: …results were found for <b><svg onload=alert(1) class=dlx444fc070></b>
6:42PM INF scan completed in 3.482 seconds
  • Homebrew
  • Snap
  • Arch (AUR)
  • Chocolatey
  • Nix
  • Cargo
$ brew install dalfox

// Capabilities

One scanner, the whole XSS workflow

Run it against one URL or a full pipeline: CLI, file batch, pipe, server, or MCP. The same engine sits underneath each one, and every finding comes back parsed, DOM-verified, and reported in a format you can act on.

Deep XSS discovery

Reflected, Stored, and DOM-based XSS with payload optimization. DOM verification (HTML parser plus a JavaScript AST) separates a reflection that executes from one that only echoes back.

reflected stored dom ast-verify

Parameter intelligence

Mining, static analysis, structural pre-encoding detection, and context-aware charset probing give every parameter a full attack profile.

WAF aware

Fingerprints popular WAFs and mutates payloads with encoding, casing, and polyglot tactics to slip through.

Built for pipelines

Pipe, file-batch, and server modes fit into CI/CD. Chain Dalfox behind your proxy, crawler, or recon stack.

REST API & MCP

Run Dalfox as a long-lived server with REST control, or expose it as an MCP tool to agents and IDEs.

Reports you can ship

Export to the format your workflow speaks, from terse CLI output to SARIF for GitHub code scanning.

JSON JSONL Markdown SARIF TOML Plain Silence

// Modes

Six ways to run Dalfox

Pick the shape that fits your target. Every mode shares the same discovery and verification engine.

$dalfox scan https://target.app

Point Dalfox at a single URL. It mines parameters, probes each context, and verifies every hit at the DOM level.

$dalfox scan urls.txt

Sweep a whole list of targets from a file, one URL per line, with the same engine and one report.

$cat urls.txt | dalfox scan

Read targets from stdin so Dalfox drops straight into your crawler or recon pipeline.

$dalfox scan https://app/post --sxss --sxss-url https://app/feed

Inject on one endpoint, then confirm the payload fires on another. Stored XSS, verified end to end.

$dalfox server

Run Dalfox as a long-lived REST API for async scan jobs, integrations, and dashboards.

$dalfox mcp

Expose Dalfox as an MCP tool so agents and IDEs can scan on your behalf.

From install to verified finding in three steps

Dalfox drops into whatever you already run. No setup ritual, no orchestration layer to stand up first.

Install

Grab Dalfox through Homebrew, Snap, Chocolatey, Nix, cargo, or a prebuilt binary. One command, no runtime to manage.

brew install dalfox

Point at a target

Give it a URL, a file, or pipe in a crawl. Dalfox mines parameters, probes contexts, and adapts.

dalfox scan https://target.app

Ship the findings

Export to SARIF, JSON, or Markdown, or proxy results to your pipeline. Findings come verified, not guessed.

dalfox scan urls.txt -f sarif -o report.sarif

Built in the open, by hunters everywhere

Dalfox is shaped by the people who run it. Open an issue, send a pull request, or trade payloads with the community. Every contribution makes the next scan sharper.

Thanks to our contributors

Ready to hunt?

Read the docs, star the repo, or drop Dalfox into your next recon loop.

--- Title: Getting Started URL: https://dalfox.hahwul.com/getting-started/ Source: content/getting-started/_index.md Language: en This section takes you from zero to a verified XSS finding in about five minutes. ## What is Dalfox? Dalfox is an open-source **XSS scanner and automation utility**. Give it a URL, a file of URLs, or a piped crawl, and it will: 1. **Discover parameters** across the query string, body, headers, cookies, and DOM. 2. **Probe contexts** to learn where each parameter lands (HTML, JavaScript, attribute, CSS). 3. **Inject payloads** tuned to each context, with optional WAF-evasion encoders. 4. **Verify findings** in the parsed response — HTML-parser evidence for markup, a JavaScript AST for script contexts — not just a text match. 5. **Report results** in the format your workflow speaks (plain, JSON, JSONL, Markdown, SARIF, TOML). ## Who is Dalfox for? - **Pentesters & bug hunters:** fast CLI reconnaissance that fits any recon stack. - **Security teams:** SARIF output drops into GitHub Advanced Security or any SAST dashboard. - **Developers:** a REST API and MCP server let CI/CD pipelines and AI agents drive scans without leaving their tools. ## Where to start Start with **[Installation](./installation/)**, then work through the **[Quick Start](./quick-start/)**. **[Configuration](./configuration/)** shows how to keep your usual flags in a config file. After that, the [Guide](../guide/) covers deeper topics like WAF bypass and Stored XSS. Coming from Dalfox v2 (Go)? Read **[Migrating from v2](./migration/)** first — subcommands were consolidated and several flags were renamed or retired. --- Title: Configuration URL: https://dalfox.hahwul.com/getting-started/configuration/ Source: content/getting-started/configuration.md Language: en Dalfox reads a config file on startup so you don't have to pass the same flags every time. An explicit CLI flag always overrides what the config sets, so it's safe to keep "defaults" here. ## Where the file lives Dalfox reads `$XDG_CONFIG_HOME/dalfox/config.toml` when `XDG_CONFIG_HOME` is set and non-empty, and `$HOME/.config/dalfox/config.toml` otherwise. A `config.json` in the same directory is read when there is no `config.toml`. You can point anywhere else with `--config`: ```bash dalfox --config ./dalfox.toml scan https://target.app ``` If no file exists, Dalfox creates a template at the default path the first time you run it. Every line in it is commented out, so it changes nothing until you edit it. ## A minimal config ```toml [scan] format = "json" output = "results.json" timeout = 15 workers = 100 encoders = ["url", "html"] ``` Run a scan and those flags apply automatically: ```bash dalfox 'https://target.app/?q=test' # → writes JSON results to results.json with workers=100 ``` ## Precedence ``` CLI flag > Config file > Built-in defaults ``` Anything on the command line wins. This lets you keep sensible defaults in the config, then override per-scan: ```bash # Config sets workers=100, but for this quick scan use 20 dalfox scan --workers 20 https://target.app ``` Scan flags need the explicit `scan` subcommand; the bare `dalfox ` form accepts only targets and the global flags. A switch the config turns on, such as `deep_scan = true`, stays on for every run, because there is no command-line flag that turns it off. See [Precedence](../../reference/config/#precedence) for the details. ## Formats Dalfox supports both TOML and JSON. TOML is the default; JSON is handy if you generate the file from a tool or UI. ```toml # ~/.config/dalfox/config.toml [scan] format = "sarif" silence = true ``` ```json { "scan": { "format": "sarif", "silence": true } } ``` ## What can I configure? Anything that has a CLI flag under `dalfox scan` can live in the `[scan]` table (`--blind` is spelled `blind_callback_url`). The file applies to CLI scans only; `dalfox server` and `dalfox mcp` ignore it. Common examples: | Key | Example | What it does | |-----|---------|--------------| | `format` | `"json"` | Output format (`plain`, `json`, `jsonl`, `markdown`, `sarif`, `toml`) | | `output` | `"report.json"` | Default output file | | `silence` | `true` | Suppress logs, emit only findings | | `timeout` | `15` | Request timeout in seconds | | `delay` | `200` | Delay between requests in ms | | `workers` | `100` | Concurrent workers per target | | `encoders` | `["url","html","base64"]` | Payload encoders | | `remote_payloads` | `["portswigger"]` | Remote payload sources | | `remote_wordlists` | `["burp"]` | Remote parameter wordlists | | `headers` | `["Accept: text/html"]` | Extra request headers | | `user_agent` | `"Dalfox Scanner"` | Default User-Agent | | `waf_bypass` | `"auto"` | WAF bypass mode (`auto`, or `off` to detect only) | | `insecure` | `true` | Skip TLS certificate verification (`false` to enforce) | | `follow_redirects` | `true` | Follow 3xx responses | See the [Config File reference](../../reference/config/) for every key. ## Secrets Keep API keys, bearer tokens, and blind-XSS callback hostnames out of the config file if you commit it. The only secret Dalfox reads from the environment is the REST server's API key: ```bash # .env or your shell profile export DALFOX_API_KEY="..." ``` Pass the rest (`-H "Authorization: …"`, `--cookies`, `-b`) at the command line and never persist them. ## Next steps - [Run your first scan](../quick-start/) - [Explore scanning modes](../../guide/scanning-modes/) - [See the full CLI reference](../../reference/cli/) --- Title: Installation URL: https://dalfox.hahwul.com/getting-started/installation/ Source: content/getting-started/installation.md Language: en Pick the installer that fits your platform. Dalfox ships as a single self-contained binary, with no runtime to manage. ## Homebrew (macOS & Linux) ```bash brew install dalfox ``` The Homebrew formula tracks the latest stable release. Source: [formulae.brew.sh/formula/dalfox](https://formulae.brew.sh/formula/dalfox). The project's own tap builds the same release from source (so it pulls in Rust) and also installs the man page and shell completions: ```bash brew install hahwul/dalfox/dalfox ``` ## Snap (Ubuntu / Linux) ```bash sudo snap install dalfox ``` ## Arch Linux (AUR) Using an AUR helper (recommended): ```bash yay -S dalfox # or paru -S dalfox ``` Manual build from the [AUR package](https://aur.archlinux.org/packages/dalfox): ```bash git clone https://aur.archlinux.org/dalfox.git cd dalfox makepkg -si ``` ## Chocolatey (Windows) ```powershell choco install dalfox ``` Installs the prebuilt `windows-x86_64` release binary and puts `dalfox` on your `PATH`. ## Nix & NixOS ```bash # Run once without installing nix-shell -p dalfox # Nix flakes: run the latest from GitHub nix run github:hahwul/dalfox -- scan https://example.com # Install into your profile nix profile install github:hahwul/dalfox ``` Dalfox lives in nixpkgs. The newest releases land in `unstable` first, so the flake above is ahead of `nixpkgs` between releases. The flake builds for `x86_64-linux`, `aarch64-linux` and `aarch64-darwin`. Intel macOS is not among them because nixpkgs `unstable` dropped `x86_64-darwin` — use the `macos-x86_64` release archive below instead. To build Dalfox against your own `nixpkgs` instead of the one this flake pins, use the overlay. In your system flake: ```nix # flake.nix { inputs.dalfox.url = "github:hahwul/dalfox"; outputs = { self, nixpkgs, dalfox, ... }@inputs: { nixosConfigurations.myhost = nixpkgs.lib.nixosSystem { specialArgs = { inherit inputs; }; modules = [ ./configuration.nix ]; }; }; } ``` Then, in a module that receives `inputs`: ```nix # configuration.nix { pkgs, inputs, ... }: { nixpkgs.overlays = [ inputs.dalfox.overlays.default ]; environment.systemPackages = [ pkgs.dalfox ]; } ``` The flake also exposes a development shell for working on Dalfox itself — the Rust toolchain, [`just`](https://github.com/casey/just) and the Crystal runtime the test harnesses need, but not the `dalfox` binary: ```bash git clone https://github.com/hahwul/dalfox && cd dalfox nix develop ``` With [direnv](https://direnv.net) installed, `direnv allow` picks the same shell up automatically from the repo's `.envrc`. ## Docker Multi-arch images (`linux/amd64`, `linux/arm64`) are published to Docker Hub and GitHub Container Registry. The binary sits at `/app/dalfox` and the image has no entrypoint, so name it in the command: ```bash docker run --rm hahwul/dalfox:latest ./dalfox scan https://example.com # or from GHCR docker run --rm ghcr.io/hahwul/dalfox:latest ./dalfox scan https://example.com ``` A bare `dalfox` fails: `/app` is not on the image's `PATH`. To scan a URL list, mount it into the container, or pipe it in with `-i`: ```bash docker run --rm -v "$PWD:/data" hahwul/dalfox:latest ./dalfox scan /data/urls.txt cat urls.txt | docker run --rm -i hahwul/dalfox:latest ./dalfox scan ``` `latest` is the newest release. Each release is also tagged `v..`, and Docker Hub adds `v.` and `v`. `ghcr.io/hahwul/dalfox:main` tracks the `main` branch. ## Cargo (from crates.io) ```bash cargo install dalfox ``` Requires Rust 1.93 or newer (the crate's `rust-version`). Builds into `~/.cargo/bin/dalfox`. ## Prebuilt binaries Grab a release archive for your OS/arch from [github.com/hahwul/dalfox/releases](https://github.com/hahwul/dalfox/releases), extract it, and drop the binary somewhere on your `PATH` (`/usr/local/bin`, `~/.local/bin`, etc.). We publish the following per release: - `macos-x86_64`, `macos-aarch64` - `linux-x86_64` (glibc), `linux-x86_64-musl` (statically linked, recommended for Alpine, Docker, and CI) - `linux-aarch64` (glibc), `linux-aarch64-musl` (statically linked) - `windows-x86_64` Archives are named `dalfox-v-`: `.tar.gz` on macOS and Linux, `.zip` on Windows. Linux also gets `.deb` and `.rpm` packages for both architectures, every archive and package ships with a `.sha256` alongside a combined `checksum.txt`, and each release carries a CycloneDX SBOM (`dalfox.cdx.xml`). ## Build from source ```bash git clone https://github.com/hahwul/dalfox cd dalfox cargo build --release # Binary at ./target/release/dalfox ``` You'll need Rust 1.93 or newer (2024 edition). Install with [rustup](https://rustup.rs/) if you don't have it. ## Verify ```bash dalfox --version ``` You should see a single line such as `dalfox 3.2.4`. ## Shell completions The `hahwul/dalfox` Homebrew tap, the AUR package, the `.deb` / `.rpm` packages and the Nix flake install bash, zsh and fish completions (and the `dalfox(1)` man page) for you — nothing else to do. Installed another way (the core `brew install dalfox` formula, Snap, Docker, Cargo, a release archive, a source build)? Generate them yourself: ```bash dalfox completion bash > /etc/bash_completion.d/dalfox dalfox completion zsh > "${fpath[1]}/_dalfox" dalfox completion fish > ~/.config/fish/completions/dalfox.fish ``` `powershell` and `elvish` are supported too — see the [CLI reference](../../reference/cli/). ## Getting help Dalfox uses [clap](https://github.com/clap-rs/clap), so help is always accessible: ```bash dalfox --help dalfox scan --help ``` ## Next steps Run your first scan in the [Quick Start](../quick-start/). If you want to tune defaults before scanning, jump to [Configuration](../configuration/). --- Title: Migrating from v2 URL: https://dalfox.hahwul.com/getting-started/migration/ Source: content/getting-started/migration.md Language: en Dalfox v3 is a complete rewrite in Rust, replacing the legacy Go architecture. The Go sources live on the [`v2` branch](https://github.com/hahwul/dalfox/tree/v2) and receive critical security backports only — all new work happens in v3. This page maps a v2 workflow onto v3: which subcommands collapsed, which flags were renamed, what was retired and why, and what you get in return. ## 1. Subcommand consolidation v3 unifies the scan subcommands behind a single entrypoint. | v2 usage | v3 equivalent | Note | | :--- | :--- | :--- | | `dalfox url [url]` | `dalfox scan [url]` | Or just `dalfox [url]` — `scan` is the default subcommand, but the bare form takes no scan flags beyond `--config`, `--debug`, `--no-color` and `-S` | | `dalfox file [file]` | `dalfox scan [file]` | Input type is auto-detected | | `dalfox pipe` | `cat targets \| dalfox scan` (or `dalfox scan --input-type pipe`) | Piped input is read from `stdin` natively | | `dalfox sxss [url]` | `dalfox scan [url] --sxss` | Stored XSS is a scan option now — see [Stored XSS](../../guide/stored-xss/) | | `dalfox server --type mcp` | `dalfox mcp` | MCP is its own stdio subcommand — see [MCP Server](../../integrations/mcp/) | | `dalfox server` | `dalfox server` | Binds `127.0.0.1` by default instead of v2's `0.0.0.0`; pass `--host 0.0.0.0` to listen on every interface. The port is still `6664`, and `--type` is gone — see [REST API Server](../../integrations/server/) | | `dalfox payload --entity-event-handler`, `--entity-useful-tags`, `--entity-special-chars`, `--remote-portswigger`, `--remote-payloadbox` | `dalfox payload event-handlers`, `useful-tags`, `special-chars`, `portswigger`, `payloadbox` | One positional selector replaces the switches. `--enum-*`, `--entity-gf`, `--make-bulk` and `--encoder-url` have no selector; run `dalfox payload --help` for the ones that exist | {{ alert(type="info", body="The legacy url, file and pipe subcommands survive as hidden aliases. All three keep their v2 shape: dalfox url URL works, and so does dalfox url -u URL. Prefer dalfox scan URL in new scripts. sxss did not survive: stored-XSS scanning moved onto the scan subcommand as the --sxss flag.") }} v2's `--rawdata`, `--har` and `--http` input switches are gone too. A captured raw HTTP request and a HAR export are auto-detected (`dalfox scan request.txt`, `dalfox scan capture.har`), or can be forced with `--input-type raw-http` / `--input-type har`. When the request line holds only a path, the scheme comes from a `:scheme` pseudo-header if there is one; otherwise an HTTP/2 signal or a `:443` Host means `https`, and anything else `http`. Put a full URL in the request line to pin it. See [Raw HTTP mode](../../guide/scanning-modes/#raw-http-mode) and [HAR mode](../../guide/scanning-modes/#har-mode). ## 2. Renamed flags | v2 flag | v3 flag | Reason & behavior | | :--- | :--- | :--- | | `-w, --worker ` | `--workers ` | Renamed, and there is no `-w` short form. Sets the number of concurrent scanning workers; the default dropped from 100 to 50. | | `-H, --header ` | `-H, --headers ` | Long form pluralized; `-H` is unchanged. May be passed more than once. | | `-C, --cookie ` | `--cookies ` | Pluralized for consistency, no `-C` short form; may be passed more than once. | | `-p, --param ` | `-p, --param ` | Same flag, now with an optional location suffix: `-p id:query`, `-p sort:body`, `-p token:header`. | | `--skip-mining-all` | `--skip-mining` | Renamed. | | `--mining-dict=false`, `--mining-dom=false` | `--skip-mining-dict`, `--skip-mining-dom` | Only the `--skip-*` forms remain (they existed in v2 too). | | `--output-request`, `--output-response` | `--include-request`, `--include-response` | Renamed; `--include-all` sets both. Still opt-in. | | `--limit-result ` | `--limit ` | Renamed; the scan stops once the cap is reached. `--limit-result-type` keeps its name. | | `--trigger ` (on `sxss`) | `--sxss-url ` | With `--sxss` and no `--sxss-url`, the check URL is auto-detected from form discovery. | | `--silence-force` (on `file` / `pipe`) | `-S, --silence` | `-S` now prints only PoC output. | | `--mass`, `--multicast`, `--mass-worker` (on `file` / `pipe`) | `--max-concurrent-targets`, `--max-targets-per-host` | Targets are always scanned concurrently; these two flags bound it. | The full, generated flag list lives in the [CLI Reference](../../reference/cli/). ## 3. Retired features and their replacements Some legacy flags and the heavyweight engines behind them were dropped to keep v3 fast, safe, and focused on XSS. | Retired v2 flag | Alternative | Why | | :--- | :--- | :--- | | `--use-bav`, `--skip-bav` | None. | **Scope**. Basic Another Vulnerability (BAV) checks are gone; v3 is strictly an XSS scanner. Use a dedicated scanner for non-XSS classes. | | `--found-action `, `--found-action-shell` | [REST API webhooks](../../integrations/server/), or pipe stdout (`dalfox scan ... \| post-script.sh`). | **Security**. Arbitrary shell execution on every finding invited RCE and throttled concurrency. | | `--skip-headless`, `--force-headless-verification` | Nothing to configure — static analysis runs by default (`--skip-ast-analysis` turns it off). | **Engine replaced**. Headless Chrome (`chromedp`) is gone. v3 verifies with a compiler-grade JavaScript parser (`oxc`), tracing data flows and DOM sinks without a browser. See [Detection Model](../../guide/detection-model/). | | `--grep `, `--skip-grepping` | None. | **Engine replaced**. Regex response matching gave way to context-aware AST analysis. `--only-poc g` (grep findings) went with it. | | `--report`, `--report-format` | `-f markdown -o `, `-f sarif -o `. | **Standardization**. Report flags folded into the output format flags — see [Output & Reports](../../guide/output/). | | `--max-cpu` | Automatic. | **Architecture**. The async scheduler (`tokio`) allocates work across cores; manual CPU pinning is obsolete. | | `--no-spinner` | Automatic. | **UI**. Spinners and progress bars draw only when stdout is a terminal and `-S` is off. The banner is dropped for `-S` and for every format except `plain`. | | `--context-aware`, `--magic-char-test` | Nothing to configure. | **Built in**. Every reflected parameter gets per-character probes (`valid_specials` / `invalid_specials`) that steer payload selection. | | `--deep-domxss`, `--detailed-analysis`, `--fast-scan`, `--har-file-path`, `--output-all` | None. | **Removed**. No v3 flag replaces them; v3 reads HAR files as input but does not record one. | Because headless verification is gone, a finding's evidence class matters more than it did in v2: `[V]` means DOM-level evidence in the parsed response, `[A]` means a static-analysis source-to-sink flow worth confirming in a browser. [Detection Model](../../guide/detection-model/) explains the grading. ## 4. What v3 adds - **MCP server (`dalfox mcp`)** — exposes Dalfox to AI coding assistants over JSON-RPC on stdio, replacing v2's `server --type mcp`. See [MCP Server](../../integrations/mcp/). - **Hard time budget (`--scan-timeout `)** — caps the payload-injection stage per target so a half-hung server can't stall the run. Preflight, discovery and mining run before that stage and are not covered by it; there only the per-request `--timeout` applies. (`dalfox server` and MCP apply their `scan_timeout` to the whole job.) - **Payload cap (`--max-payloads-per-param `)** — keeps combinatorial payload expansion (bypasses × encoders) from turning into a request burst. - **Preflight (`--dry-run`)** — reports discovered parameters and an estimated request count without sending a single payload. - **Adaptive WAF evasion (`--waf-evasion`)** — the flag existed in v2 as a fixed `worker=1, delay=3s` preset. In v3 it randomizes inter-request timing (whether or not a WAF was detected) and escalates a cooldown when blocked responses cluster. See [WAF Bypass](../../guide/waf-bypass/). - **HTTP parameter pollution (`--hpp`)** — duplicates query parameters to slip past string-matching WAF layers. - **Managed OAST (`--blind-oob`)** — registers an interactsh session and correlates callbacks to the payload that caused them, alongside the plain `-b` callback URL. - **Pacing and retries (`--rate-limit`, `--retries`)** — a global requests-per-second cap shared by every worker, and backoff retries on 5xx and transient errors. - **Resumable and incremental runs (`--state-file`, `--baseline`)** — skip targets a previous run completed, or report only findings new since an earlier JSON report. - **Session monitoring** — on automatically whenever the scan carries credentials (`--session-check` pins it to a marker you choose); an authenticated scan whose session drops is reported as incomplete instead of clean. See [Session monitoring](../../guide/scanning-modes/#session-monitoring). - **Shell completions (`dalfox completion `)** — bash, zsh, fish, PowerShell, and Elvish. ## Next steps - Re-read the [scanning modes](../../guide/scanning-modes/) — the flags you reach for by reflex may have moved. - Move your recurring v2 command line into a [config file](../configuration/). - Skim the [CLI Reference](../../reference/cli/) for flags that have no v2 ancestor at all. --- Title: Quick Start URL: https://dalfox.hahwul.com/getting-started/quick-start/ Source: content/getting-started/quick-start.md Language: en This page walks you from install to a verified finding. We'll use an intentionally vulnerable demo target so you can see real output. {{ alert(type="warning", body="Only scan targets you're authorized to test. Dalfox fires real XSS payloads.") }} ## 1. Scan a single URL ```bash dalfox 'https://xss-game.appspot.com/level1/frame?query=test' ``` The first argument is the target. Dalfox auto-detects that it's a URL and runs the `scan` subcommand implicitly. Quote any URL that contains `?` or `&`: the shell treats them as special characters, and zsh aborts an unquoted `?` with `no matches found`. You'll see: - A banner with the version. - `INF` lines as Dalfox discovers parameters and probes contexts. - A `WRN XSS found N XSS` summary, then a `[POC][V]…` (vulnerable) or `[POC][R]…` (reflected) line for each finding. Under it come the issue, the exact payload that worked, and the response line it landed in. - A closing `INF scan completed in … seconds`. The bare form accepts only the global flags (`--config`, `--debug`, `--no-color`, `-S`). Any other scan flag needs `dalfox scan …`, the form the rest of this page uses. ## 2. Scan from a file Feed a list of URLs from your crawler: ```bash # urls.txt, one target per line dalfox scan urls.txt ``` Each URL runs through the same pipeline. Findings are printed after the end-of-scan `WRN XSS found N XSS` summary; add `--stream-findings` to print each one the moment it is verified. ## 3. Scan from a pipeline Dalfox reads from `stdin` when you pipe: ```bash cat urls.txt | dalfox # or combined with your recon tools: waybackurls example.com | gf xss | dalfox ``` ## 4. Get JSON output Pair Dalfox with `jq`, a dashboard, or CI: ```bash dalfox scan 'https://target.app/search?q=test' -f json -o report.json ``` Every format except `plain` (so `json`, `jsonl`, `markdown`, `sarif`, `toml`) suppresses the banner, so the file stays clean. The exit code is CI-friendly too: `0` means no findings, `1` means findings, and `2` means an error or a result you can't trust (every target unreachable, too many lost requests, an expired login). See [Exit codes](../../guide/output/#exit-codes). ## 5. Authenticated scans Pass cookies, headers, or a custom method: ```bash dalfox scan https://api.target.app/v1/users \ -X POST \ -H "Authorization: Bearer eyJ..." \ -H "Content-Type: application/json" \ -d '{"name":"test"}' \ --cookies "session=abc123" ``` Or point Dalfox at a **raw HTTP request** file you captured from your proxy: ```bash dalfox scan --input-type raw-http request.txt ``` Or replay an entire **HAR** export (from browser DevTools or a proxy) — Dalfox scans every request in it, preserving each one's method, headers, cookies, and body: ```bash dalfox scan capture.har # auto-detected dalfox scan --input-type har capture.har ``` ## 6. Catch Blind XSS Use an out-of-band callback (Interactsh, Burp Collaborator, XSS Hunter, etc.): ```bash dalfox scan https://target.app \ -b https://your-callback.interact.sh ``` Blind payloads go into the parameters the request already carries (query, a form-encoded `-d` body, `-H` headers, cookies) and into the same-origin POST forms on the page. Parameters found later by discovery or mining get none. If a payload fires later in an admin panel, your callback server records it. Or let Dalfox manage an [interactsh](https://github.com/projectdiscovery/interactsh) (OAST) server for you — it registers a session, correlates callbacks to the originating payload, and polls automatically: ```bash dalfox scan https://target.app --blind-oob # public interactsh mesh dalfox scan https://target.app --blind-oob=oast.fun # pick servers ``` A callback that arrives becomes a `V` finding with `detection_method: oob`. Use `--blind-oob-secret` for a self-hosted server and `--blind-oob-wait` to control how long Dalfox keeps polling after the scan finishes. See [Blind XSS](../../guide/scanning-modes/#blind-xss) for the details. On the OAST channel, `--insecure` (on by default) only reaches a server you named with `--blind-oob=`, such as a self-hosted one behind a self-signed certificate. The public interactsh servers are always TLS-verified. ## 7. Dry-run first Use `--dry-run` to preview what Dalfox would scan: ```bash dalfox scan https://target.app --dry-run ``` It discovers parameters and estimates request volume without firing any payloads. ## Reading the output Each finding is tagged: | Tag | Meaning | |-----|---------| | `[V]` | **Vulnerable**: Dalfox asserts the input is exploitable — the payload reached an executable position in the parsed response (for example a DOM element carrying Dalfox's marker), or an out-of-band callback fired | | `[A]` | **AST-detected**: static JS analysis found a source→sink flow | | `[R]` | **Reflected**: payload appeared in the response, but no DOM evidence | | `[I]` | **Informational**: not an XSS claim, e.g. a known-vulnerable JS library from the opt-in `--detect-outdated-libs` | `V` and `A` findings are actionable. `R` findings are worth a look but may be filtered further downstream. `[V]` is not browser execution. Dalfox drives no browser, by design. A pure client-side DOM-XSS reports as `[A]` today and is worth confirming in a browser. Each finding also carries `detection_method` (how it was found) and `confidence` (how strongly the evidence supports the claim) — see [Detection Model](../../guide/detection-model/). ## Next steps - Learn the different [scanning modes](../../guide/scanning-modes/). - Understand how [parameters are discovered](../../guide/parameters/). - Tune [payloads and encoders](../../guide/payloads/) for harder targets. - Save your favorite flags in a [config file](../configuration/). --- Title: Guide URL: https://dalfox.hahwul.com/guide/ Source: content/guide/_index.md Language: en The guide covers the concepts that make Dalfox effective: how parameters are discovered, which payloads run where, how Stored XSS detection works, how to handle WAFs, and what each finding actually proves. Each page is self-contained. Read them in order the first time, then come back as reference. ## Topics - **[Scanning Modes](./scanning-modes/):** Single URL, file batch, pipe, raw HTTP, HAR, stored and blind XSS, server, and MCP. - **[Parameters & Discovery](./parameters/):** How Dalfox finds inputs, prunes false-positives, and mines wordlists. - **[Payloads & Encoding](./payloads/):** Built-in payload families, encoders, and custom wordlists. - **[WAF Bypass](./waf-bypass/):** Fingerprinting WAFs and applying evasive mutations. - **[Stored XSS](./stored-xss/):** Inject on one URL, verify on another. - **[Output & Reports](./output/):** Plain, JSON, JSONL, Markdown, SARIF, TOML. - **[Detection Model](./detection-model/):** What `V` / `R` / `A` / `I` mean, how each finding was produced, and what the evidence proves. --- Title: Detection Model URL: https://dalfox.hahwul.com/guide/detection-model/ Source: content/guide/detection-model.md Language: en Every Dalfox finding answers three separate questions. Reading them as one scale is the single most common source of confusion about the output, so they are separate fields: | Axis | Field | Question | |------|-------|----------| | **Confidence** | `type` — `V` / `R` | Can Dalfox claim this is a vulnerability? | | **Method** | `detection_method` | How was it found? | | **Impact** | `severity` | How bad is it if exploited? | Two of those three vary independently today. **`severity` does not**: for XSS findings it is currently a restatement of the tier (`V` → `High`, `A` → `Medium`, `R` → `Info`), so filtering or sorting on it tells you nothing that `type` didn't. It carries real information only on `I`, where it comes from the library advisory. Treat it as a display convenience until it grades impact on its own. `[A]` predates that split. It answers the *method* question while sitting in the `type` field, which is why nobody (including the code) could say where it belonged on the confidence scale. It is being absorbed; see [Migration](#migration) below. This page exists because the split was not visible from the output alone. It was worked out in [issue #1238](https://github.com/hahwul/dalfox/issues/1238) with [@OSTARA711](https://github.com/OSTARA711), whose write-up is the basis for the model here. ## Confidence: what `type` means | Tag | Name | Means | |-----|------|-------| | `V` | **Vulnerable** | Dalfox asserts this input is exploitable. Act on it. | | `R` | **Reflected** | The payload came back in the response, but its position was not confirmed exploitable. A signal, not a claim — confirm it yourself. | | `A` | AST-detected | Transitional — a method label. See [Migration](#migration). | | `I` | Informational | Not an XSS claim at all (e.g. a known-vulnerable JS library, CWE-1104). | Filter with `--only-poc` (e.g. `--only-poc v`, `--only-poc v,a`, `--only-poc i`). ### What `V` does not mean `V` is **not** browser execution. Dalfox drives no browser and speaks no CDP; it never renders a page or watches an `alert()` fire. For the request-based methods, `V` means the payload was found in a *DOM tree parsed from a real HTTP response* — static analysis, on stronger evidence than the raw string match behind `R`. There is exactly one method where Dalfox observes real execution: **out-of-band callbacks** (blind XSS with `--blind-oob`). When an injected `` | `-b`/`--blind` or `--blind-oob` is set | Most payload templates carry a marker (`class={CLASS}` or `id={ID}`) so the verification stage can positively identify its own element in the DOM. A few short payloads carry no marker so they fit length-capped reflections; for those, verification looks for the payload's own event handler or `` | `-b`/`--blind` 또는 `--blind-oob`가 설정된 경우 | 대부분의 페이로드 템플릿은 마커(`class={CLASS}` 또는 `id={ID}`)를 지니고 있어, 검증 단계에서 DOM 내에서 자신의 요소를 확실하게 식별할 수 있습니다. 길이 제한이 있는 반사에 들어가도록 마커를 뺀 짧은 페이로드도 몇 개 있는데, 이런 페이로드는 파싱된 응답에서 페이로드 자신의 이벤트 핸들러나 `