FUZZ can sit in a URL, header, or POST body
ffuf takes a wordlist and substitutes each entry wherever you place the FUZZ keyword. That model covers directory paths, virtual-host headers, query names or values, JSON fields, and form data. Matchers keep responses with useful status codes, sizes, word counts, line counts, regular expressions, or time-to-first-byte behavior. Filters remove the responses you already know are noise. The tool does not decide what a finding means for you.
Multiple wordlists can run in clusterbomb, pitchfork, or sniper mode. Results can be written as JSON, newline-delimited JSON, CSV, HTML, or Markdown. A replay proxy sends matched requests to another inspection tool. This suits an experienced tester who wants a fast request generator rather than a guided scanner.
Forty threads and no rate cap need an owner
The default configuration uses 40 concurrent threads and sets requests per second to 0, meaning no explicit rate limit. Those defaults can be fine in a lab and reckless against a shared staging service. -rate, -p, -timeout, and -maxtime let you put a ceiling around the job. Recursion has its own per-job maximum, and -sf stops when more than 95 percent of responses are HTTP 403.
Authorization belongs before the command. ffuf sends the requests you describe, including cookies, custom headers, client certificates, and POST data. Its security policy treats the target's behavior as the target owner's concern, while vulnerabilities in ffuf itself use private disclosure. Keep the target list, allowed paths, request rate, and test window in the engagement record.
What happened when we ran it
Our sandbox installed commit 8d65e03 in 19 seconds, downloading 17 Go packages. The build passed in 21 seconds. Go test then finished in 9 seconds with 24 passing tests and no failures. The unprivileged Debian container had 3 CPUs, 8 GB of RAM, and no secrets. We did not point the binary at an external target, so these results cover package and test health rather than request throughput or finding accuracy.
The checkout contained 150 files, roughly 14,216 lines of source, and occupied 0.8 MB. We found 4 CI workflow files and a tests directory, but no Dockerfile. You can download a release binary or install it with Go, Homebrew, Scoop, or Winget. Our measured path gives the project a cleaner starting point than a security tool that fails before the first request.
Automatic calibration still loses dynamic error pages
Auto-calibration tries to learn a target's boring response and filter it away. Open issue 928 documents a boundary: when a 404 page reflects the guessed path, its content length changes with every word. Word or line counts can move too. In that case -ac may report that it found no common filtering value, leaving every error page in the results. A fast run full of false positives is still a bad run.
Start with a small wordlist and inspect the baseline responses. Filter on a stable status code, regular expression, word count, or another property the application holds constant. Interactive mode lets you change filters while a job is paused, then removes existing false positives from stored matches. It cannot recover filtered responses; relaxing a filter requires restart, which begins the job again.
Recursion only descends through a URL path
The current recursion contract requires the URL to end in FUZZ. Default recursion follows directory-like redirects, while greedy mode descends on every match. Open issue 923 asks to extend the same idea to values inside bodies and headers, but that behavior is absent. If the job is extracting one character at a time from POST responses, an outside script must manage the next input.
Long jobs have another unfinished edge. Issue 900 asks to resume from a known word after a 429 response, WAF block, or network interruption. The interactive shell can pause, change the rate, inspect queued jobs, save matches, or restart. It does not provide the requested start-from-word control. Split large wordlists beforehand or record enough position data to avoid replaying the whole set.
v2.3.0 is active, while two docs details lag source
GitHub showed 16,767 stars and 234 open issues and pull requests combined on September 29, 2026. The repository was pushed on September 26, and v2.3.0 shipped on September 9. That release added preflight and postflight requests with variable extraction, bounded saved response snapshots and header sizes, fixed concurrency defects, and introduced a mock-target integration harness. Recent work and issue activity point to active maintenance.
The README still says Go 1.20 or newer and its pasted usage banner says v2.1.0. Current go.mod declares Go 1.26.0, so source builders should trust the module file and checked-out commit over those README lines. Multi-wordlist report users should also watch open pull request 924, which says CSV, HTML, and Markdown values can land under the wrong headers until its fix merges.
ffuf is the best first pass when you know the request
ffuf earns a place in an authorized tester's kit because 24 of 24 tests passed and the command maps cleanly to raw HTTP variation. It is less persuasive when the hard part is crawling JavaScript, maintaining a browser session, interpreting a business workflow, or resuming a huge campaign. Gobuster and dirsearch offer narrower discovery workflows. Katana is the better companion when links and scripts must reveal the surface first.
Use ffuf after you can write down the request template and the signal that separates a useful response from background noise. Begin at a rate the target owner approved, save structured output, and replay only the matches that deserve closer inspection. The green 49-second install, build, and test path removes setup doubt. It does not remove the judgment required to choose the wordlist, filters, or legal boundary.

