dalfox-rs 0.2.0

Type-safe asynchronous wrapper for the Dalfox XSS scanner with streaming output, stored XSS support, and multi-format result formatting
Documentation

dalfox-rs

Crates.io Documentation License: MIT

Available on Crates.io: https://crates.io/crates/dalfox-rs

A strictly-typed, asynchronous Rust binding for the Dalfox XSS Scanner.

dalfox-rs wraps the Dalfox binary with full coverage of its CLI flags, streaming JSON output into typed Rust structs, making XSS scanning composable and panic-free inside fuzzers, proxies, or CI/CD pipelines.

Features

  • Full CLI coverage — every Dalfox flag exposed as a typed builder method
  • Streaming output — real-time callbacks as findings are discovered
  • Stored XSS — first-class sxss mode for persistent XSS detection
  • Multi-format output — JSON, CSV, Markdown, and plain text
  • Diagnostic capture — stderr, parse errors, exit codes all preserved
  • Result filtering — query by severity, event type, or verified status

Installation

[dependencies]
dalfox-rs = "0.2.0"
tokio = { version = "1", features = ["full"] }

Prerequisite: The dalfox binary must be in your system $PATH or specified via .binary_path().

Setup (one-command)

Option A: Setup script (auto-detects Go/Homebrew or downloads binary)

./setup.sh

Option B: Go install

go install github.com/hahwul/dalfox/v2@latest

Option C: Homebrew

brew install dalfox

Option D: Pre-built binary

./setup.sh --binary
# installs to ~/.local/bin/dalfox

Quick Start

use dalfox_rs::{Dalfox, DalfoxResult, OutputFormat};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let runner = Dalfox::builder()
        .request_timeout(10)   // per-request timeout (seconds)
        .scan_deadline(300)    // overall scan deadline (seconds)
        .workers(100)
        .headless(true)
        .build();

    let result: DalfoxResult = runner.scan_url("http://example.com?q=test").await?;

    for finding in &result.findings {
        println!("{}", finding); // Display impl gives readable output
    }

    // Output as CSV for spreadsheet import
    println!("{}", result.format_as(OutputFormat::Csv));

    Ok(())
}

Streaming Output

Process findings in real-time as they're discovered:

let result = runner.scan_url_streaming("http://example.com?q=test", |finding| {
    eprintln!("LIVE: {}", finding);
    // Send to webhook, update progress bar, etc.
}).await?;

Stored XSS (sxss mode)

Detect persistent XSS via separate injection and trigger URLs:

let result = runner.scan_sxss(
    "http://example.com/comment?body=test",  // inject here
    "http://example.com/view-comments",       // check here
).await?;

Advanced Configuration

let runner = Dalfox::builder()
    .waf_evasion(true)
    .cookie("session_id=12345")
    .header("Authorization: Bearer my_token")
    .delay(500)
    .param("id,q,lang")
    .blind_callback("https://my.callback.domain.com")
    .follow_redirects(true)
    .deep_domxss(true)
    .ignore_return("302,403,404")
    .tamper("space2comment")
    .found_action("notify-send XSS_FOUND")
    .binary_path("/usr/local/bin/dalfox")
    .build();

Result Filtering

let verified = result.verified_findings();
let critical = result.high_severity_findings();

if result.has_parse_errors() {
    eprintln!("Warning: {} output lines failed to parse", result.parse_errors.len());
}

Execution Modes

Mode Method Description
URL scan_url() Scan a single target URL
File scan_file_raw() Analyze a raw HTTP request file
Pipe scan_pipe() Pipeline multiple URLs via stdin
Stored XSS scan_sxss() Detect persistent XSS

All modes have _streaming variants for real-time callbacks.

License

MIT License