Skip to main content
Get started with whatwaf by running your first WAF detection scan. This guide covers both CLI and library usage.

CLI quick start

The fastest way to detect a WAF is using the command-line interface.
1

Run a basic scan

Scan a URL to detect if it’s protected by a WAF:
whatwaf https://example.com
2

Understand the output

whatwaf sends multiple probe requests and reports results:
* scanning https://example.com
* plain request probe -> https://example.com
    - no detection (status=200)
* xss probe -> https://example.com/?q=<script>alert(1)</script>
    + waf=(cloudflare) status=403
~ detected waf: Cloudflare
Each probe tests different attack patterns:
  • plain request - Baseline request without malicious payloads
  • xss - Cross-site scripting payload
  • sql injection - SQL injection attempt
  • lfi - Local file inclusion attempt
When a WAF is detected, scanning stops early.
3

Try advanced options

Customize scans with additional flags:
# Follow redirects
whatwaf -L https://example.com

# Set custom timeout (in seconds)
whatwaf -T 30 https://example.com

# Use a proxy
whatwaf -x http://localhost:8080 https://example.com

Library quick start

Integrate WAF detection into your Rust applications.
1

Basic scan

Use scan_url to detect WAFs programmatically:
use whatwaf::{scan_url, ScanConfig};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let result = scan_url(
        "https://example.com",
        ScanConfig {
            timeout: 10,
            follow_redirects: true,
            proxy: None,
        },
        None,
    )?;

    if let Some(last) = result {
        if let Some(wafs) = last.detected_wafs {
            println!("WAF detected: {}", wafs.join(", "));
        } else {
            println!("No WAF detected");
        }
    }

    Ok(())
}
2

Use probe callbacks

Monitor each probe request as it executes:
use whatwaf::{scan_url, ScanConfig, ProbeResult};

let result = scan_url(
    "https://example.com",
    ScanConfig {
        timeout: 10,
        follow_redirects: true,
        proxy: None,
    },
    Some(|probe: &ProbeResult| {
        println!("Probe: {} -> {}", probe.probe_name, probe.url);
        println!("Status: {}", probe.status);
        
        if let Some(wafs) = &probe.detected_wafs {
            println!("Detected: {:?}", wafs);
            // Return false to stop scanning
            return false;
        }
        
        // Return true to continue scanning
        true
    }),
)?;
The callback receives a ProbeResult with:
  • probe_name - Type of probe (“plain request”, “xss”, etc.)
  • url - Full URL including any probe parameters
  • status - HTTP status code
  • detected_wafs - Optional list of detected WAF names
Return false to stop scanning early, or true to continue.
3

List available detectors

Get all WAFs that whatwaf can recognize:
use whatwaf::list_detectors;

fn main() {
    println!("Detectable WAFs:");
    for detector in list_detectors() {
        println!("  - {}", detector);
    }
}

Understanding scan results

When a WAF is detected, you’ll see which probe triggered it:
* scanning https://example.com
* plain request probe -> https://example.com
    - no detection (status=200)
* xss probe -> https://example.com/?q=<script>alert(1)</script>
    + waf=(cloudflare) status=403
~ detected waf: Cloudflare
The scan stops after the first detection. Common indicators:
  • Status 403 (Forbidden)
  • Status 406 (Not Acceptable)
  • Vendor-specific headers or response bodies

Next steps

CLI reference

Explore all command-line options

API reference

Deep dive into library functions and types

Detectors

See all supported WAF detections

How it works

Learn about detection methods

Build docs developers (and LLMs) love