# Dalfox

> Use when scanning a URL or parameter for XSS (reflected, DOM, stored, blind), enumerating reflected parameters, or when the user explicitly mentions "dalfox" or "XSS scan". Runs as CLI (`dalfox scan`) or MCP server (6 tools). Authoritative workflows for dalfox v3 (Rust). Not for non-XSS vulnerabilities.

- Skill: `hahwul/dalfox` (Agent Skill, multi-file: 8 files)
- Install (CLI): `npx skillmds@latest add hahwul/dalfox`
- Raw SKILL.md: https://api.skillmd.com/api/skills/hahwul/dalfox/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: hahwul (https://skillmd.com/u/hahwul)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/hahwul/dalfox

---


# Dalfox: XSS Scanning Skill

**Core principle**: XSS scanning sends attack payloads. Always start with authorization.

## 1. Authorization (non-negotiable first step)

Before any scan:

- Confirm the target is owned by the user, a sanctioned test lab, CTF, or authorized engagement.
- If the target is not obviously safe (e.g. not `testphp.vulnweb.com`, `xss-game.appspot.com`, or a clear lab host), ask explicitly:

  > "Confirm you are authorized to send XSS payloads to this target."

Do not proceed without a clear affirmative. Record the scope in one sentence when the user says yes.

## 2. Choose Execution Mode (check in order)

1. **MCP tools available** (`scan_with_dalfox`, `preflight_dalfox`, or tools prefixed `mcp__dalfox__`)  
   → **Prefer MCP**. Async, cancellable, progress tracking, structured results.

2. **`dalfox` binary on PATH** (`command -v dalfox`)  
   → Use CLI.

3. **Neither**  
   → Tell the user the install options: `brew install dalfox`, `cargo install --path .`, or `nix run github:hahwul/dalfox`.

When both are present, MCP is usually the better agent experience for anything longer than a quick smoke test.

See `references/mcp.md` for the exact 6 tools and parameter schemas.

## 3. Core Workflows

### A. Safe Preflight (always do this on big or sensitive targets)

**MCP**:
```json
{"target": "https://target/?q=test", "skip_mining": true}
```
Use `preflight_dalfox`. Look at `estimated_total_requests` and `reachable`.

**CLI**:
```bash
dalfox scan https://target/?q=test --dry-run --skip-mining
# Prefer --format json for machine parsing; check meta.warnings if you passed -p
```

If the number is huge or `reachable == false`, report back to the user before sending real payloads.

### B. Standard Single-Target Scan (MCP preferred)

1. Preflight (see above) when the surface is unknown or large.
2. Start the scan:
   - **MCP short smoke** (one call, no poll loop):
     ```json
     {"target":"https://target/?q=test","param":["q"],"skip_mining":true,"skip_discovery":true,
      "max_payloads_per_param":20,"wait":true,"wait_timeout_sec":120}
     ```
   - **MCP long scan**: `scan_with_dalfox` with `wait=false` → store `scan_id` → poll `get_results_dalfox`. Prefer explicit `param` (`["q:query"]` when location is known).
   - **CLI**: `dalfox scan https://target/?q=test -p q --skip-mining ...`  
     Bare `-p name` is fine for query params (synthesized if discovery was skipped). Use `name:location` for body/header/cookie/json (`-p user:body`). GraphQL `variables` and XML/SOAP bodies are auto-detected as `graphql`/`xml` injection points from a matching `-d` body (or raw-http/har). Cap volume with `--max-payloads-per-param`.
3. Poll only when not using `wait=true`.
4. Present findings using the rules in `references/results.md` (lead with V, surface `type_description` and `inject_type`).
5. Clean up: `delete_scan_dalfox` (MCP) or just let the process end (CLI). Terminal jobs auto-expire after 1 h.

### C. Authenticated / Proxied / Blind XSS

See the concrete flag combinations in `references/cli.md` (search for "Polite authenticated scan" and "Blind").

**Authenticated scans carry a session that can die mid-run.** Dalfox monitors
for that automatically whenever credentials are supplied, and marks affected
targets `incomplete` / `SESSION_LOST` with `meta.incomplete: true` rather than
reporting them clean. Never summarize `findings_count: 0` as "no XSS found"
without checking `meta.incomplete` first. Tighten the check with
`--session-check '<regex>'` / `--session-check-url`; see `references/cli.md`.

The **server and MCP** surfaces monitor too, on the same trigger (a `cookie` /
`Authorization` header on the scan request). They have no `meta` envelope, so a
scan whose session died settles `status: "error"` with an `error_message`
starting `SESSION_LOST:`. Same rule for you: on a scan that returns zero
findings, check `status` before saying the target is clean.

Two ways to catch blind XSS (CLI):
- `--blind <url>` — you run the listener (interact.sh, Burp Collaborator, XSS Hunter) and watch it yourself.
- `--blind-oob[=servers]` — Dalfox manages an interactsh (OAST) session for you: it registers, correlates each callback to the originating payload, and polls automatically (`--blind-oob-secret` for self-hosted, `--blind-oob-wait` to tune end-of-scan polling). CLI-only for now.

Common MCP pattern:
- Supply `headers`, `cookies`, `proxy`, `blind_callback_url`, and explicit `param` with location hints. (MCP/server expose `--blind`-style callbacks; the managed `--blind-oob` lifecycle is CLI-only.)

### D. File / Many Targets

```bash
dalfox scan targets.txt --skip-mining --workers 10 --delay 150
```

Combine with `--max-concurrent-targets` and `--max-targets-per-host` for safety.

### E. Raw Captured Request (raw-http) / HAR export (har)

```bash
# One captured request:
dalfox scan -i raw-http captured-request.txt --blind https://your.interact.sh
# A whole HAR / proxy export (every request, method+headers+cookies+body preserved):
dalfox scan capture.har                 # auto-detected
dalfox scan -i har capture.har          # explicit
```

Excellent when the interesting parameters live in cookies, custom headers, or a complex JSON body. `har` fans a multi-request capture out into one target per `log.entries[].request` (deduped by URL+method); `raw-http` is the single-request form. See `references/cli.md`.

### F. Stored XSS (SXSS)

```bash
dalfox scan https://target/submit --sxss --sxss-url https://target/view --sxss-retries 5
```

### G. Server Mode (when user wants a persistent API)

```bash
dalfox server --port 6664 --api-key "$TEAM_KEY" --allowed-origins "https://team.example.com"
```

See `references/server-and-payload.md` for endpoints, CORS/JSONP details, and when to choose server vs MCP.

## 4. Result Interpretation (read this every time)

See the full guide in `references/results.md`.

Key points for agents:
- Three separate axes: `type` (`V`/`A`/`R`/`I`, the claim) + `detection_method`
  (`reflection` / `dom-verification` / `ast` / `oob` / `library`, how it was
  found) + `severity`. Do not read them as one scale.
- `V` means "dalfox asserts this is exploitable" — **not** browser execution.
  Dalfox drives no browser by design; only `detection_method: "oob"` observes a
  real one. Never report `V` as "watched it fire".
- Select AST findings with `detection_method == "ast"`, not `type == "A"`.
- `confidence` (`high`/`low`) + `confidence_reason` grade the claim; sort a
  large `A` batch on them. Machine formats only — plain output omits them.
- `inject_type` tells you the reflection context (`inHTML`, `inJS`, `inATTR`, etc.).
- The parameter *location* (query/body/header/...) is in the `location` field,
  and also visible in `data` + `method`.
- `include_request` / `include_response` are opt-in only — never enable them by default.

## 5. Performance & Scope Recipes

See `references/advanced.md` for the detailed recipes:

- "Too many parameters / too slow" → preflight + `--skip-mining` + explicit `-p` (`name:location` when not query) + `max_payloads_per_param` / `--max-payloads-per-param`
- "WAF present" → the matrix of `--waf-bypass`, `--force-waf`, `--waf-evasion`
- "Need custom payloads or markers" → `--custom-payload`, `--inject-marker`, `--custom-alert-*`
- "Captured request testing" → `-i raw-http` (single request) or `-i har` (whole proxy/DevTools export)
- Concurrency / politeness caps

## 6. Configuration & Environment

See `references/config.md`.

- `--config path` overrides everything.
- Default location: `$XDG_CONFIG_HOME/dalfox/` or `~/.config/dalfox/`.
- CLI flags always beat config values (enforced by `apply_to_scan_args_if_default`).
- A `silence = true` in config suppresses the banner the same way `-S` does.

## 7. Boundaries — What Dalfox Is Not For

- Non-XSS issues (SQLi, SSRF, auth bypass, IDOR, etc.).
- Unauthenticated mass recon on targets the user has not explicitly authorized.
- Replacing human code review for complex DOM-XSS — AST findings (`A`) still need manual verification in many cases.

## 8. Quick Reference — Where to Look Next

- Exact CLI flags + safe combos → `references/cli.md`
- MCP tool schemas + gotchas (including why `cookie_from_raw` is absent) → `references/mcp.md`
- Finding types, output formats, POC types, error codes, exit codes → `references/results.md`
- Config precedence, paths, banner behavior → `references/config.md`
- Server API + `dalfox payload` selectors → `references/server-and-payload.md` (single file; not separate `server.md` / `payload.md`)
- WAF recipes, mining control, bare vs `name:location` `-p`, raw-http, HPP, custom payloads → `references/advanced.md`

## 9. AGENTS.md Invariants (this skill must respect)

- `include_request` / `include_response` are opt-in only.
- Config never overrides an explicit CLI/MCP value.
- Concurrency is bounded (`workers`, `max_concurrent_targets`, `max_targets_per_host`).
- Exit codes: 0 = clean, 1 = findings, 2 = error.
- All three interfaces (CLI, server, MCP) share the error codes from `cmd::error_codes`.

When in doubt, re-read the relevant reference file and the project `AGENTS.md` before acting.

