Monthly vulnerability scanning: first month free! Learn more →
Hero

WE ARE

HACKIFY

ffuf - Fuzz Faster U Fool

ffuf - Fuzz Faster U Fool

July 25, 2026 · 6 min read · tools

web recon

What is ffuf?

ffuf (Fuzz Faster U Fool) is an open-source web fuzzer, written in Go and created in 2018 by Joona Hoikkala (@joohoi). You use ffuf to discover places in a web application that you would not run into by just clicking around: hidden directories and files, undocumented parameters, virtual hosts and subdomains. Instead of guessing, you work through a wordlist. ffuf requests each word from that list at the server and shows which ones exist.

Where in the request that word lands is up to you, marked with the keyword FUZZ. You place FUZZ at the spot you want to probe and ffuf fills in the next line from the list each time. From the status code and the size of every response you can tell whether something exists at that address. ffuf sends many requests at once and works through such a list in seconds, which makes it our default tool for the enumeration phase of a web pentest.

The position of that keyword determines what you are looking for. Put FUZZ in the path and you search for directories and files. Put it in the Host header and you search for virtual hosts. Put it in the query string or the body and you test parameters. One tool covers the whole enumeration job that way.

What do we use ffuf for?

In a web application pentest, ffuf is one of the first tools we reach for. Think of a forgotten /admin panel, a backup like database.sql.bak, an exposed .git directory or a test endpoint that was never cleaned up. Such finds are often the starting point of a serious vulnerability.

We also use ffuf to discover virtual hosts that are not in DNS, to find hidden GET and POST parameters, and to enumerate subdomains. ffuf does the same work as Gobuster and the older Wfuzz, but is more flexible in where you fuzz and therefore our default choice. What ffuf surfaces, we then investigate by hand in Burp Suite, and concrete vulnerabilities we follow up with Nuclei or SQLMap.

Installation

On Kali, ffuf is in the standard repositories:

sudo apt install ffuf

If you have a Go toolchain, you pull the latest version directly with go install github.com/ffuf/ffuf/v2@latest. On macOS brew install ffuf works. For the wordlists we use SecLists, which on Kali lives under /usr/share/seclists/.

Basic usage

The minimal command consists of a wordlist (-w) and a URL (-u) containing the FUZZ keyword. ffuf replaces FUZZ with each line from the list and shows which responses are worth a look:

# Find hidden directories and files: FUZZ sits in the path
ffuf -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt \
     -u https://target.example.com/FUZZ

By default ffuf only shows responses with an interesting status code (among others 200, 301, 302, 401, 403 and 500). Per hit you see the status code, the size in bytes, and the number of words and lines. You will need those numbers shortly to filter out noise.

Important flags

Flag Purpose Example
-w Wordlist (with :NAME a custom keyword) ffuf -w list.txt:FUZZ -u https://target/FUZZ
-u Target URL containing the FUZZ keyword ffuf -w list.txt -u https://target/FUZZ
-mc Only show these status codes (match) ffuf ... -mc 200,204,301,403
-fc Hide these status codes (filter) ffuf ... -fc 404,403
-fs Hide responses of this size ffuf ... -fs 4242
-fw Hide responses with this word count ffuf ... -fw 12
-fl Hide responses with this line count ffuf ... -fl 1
-ac Autocalibration: learn and filter the default page ffuf ... -ac
-e Append extensions to the keyword ffuf ... -e .php,.bak,.zip
-recursion Automatically keep searching discovered directories ffuf ... -recursion -recursion-depth 2
-H Send an extra header (may contain FUZZ) ffuf ... -H "Host: FUZZ.target"
-X / -d HTTP method and request body (may contain FUZZ) ffuf ... -X POST -d "user=admin&pass=FUZZ"
-t Number of concurrent threads (default 40) ffuf ... -t 100

Filtering: cutting out the noise

Sometimes a server answers every URL with a 200 OK, even for paths that do not exist. Instead of a proper 404 you then get a standard ’not found’ page with code 200. To ffuf every line in the list looks like a hit that way, and the output becomes useless. Filtering removes that noise.

You filter on the characteristics of that default page. If you notice every false hit is exactly 4242 bytes, you hide those with -fs 4242. Often -fw (word count) or -fl (line count) is more stable than the size, because a dynamic page can vary in bytes while staying the same in structure.

If you do not know those values in advance, -ac does the work. With autocalibration ffuf first sends a few requests to random, definitely non-existent paths, measures what the ’not found’ response looks like and filters exactly those responses out automatically. In practice you often start a scan with -ac and then refine by hand with -fs or -fw if any noise slips through.

Practical examples

Directories and files with extensions. Besides directory names you also want to find files. With -e you append extensions to each word, so ffuf tries config as well as config.php and config.bak. Autocalibration keeps the output clean.

ffuf -w /usr/share/seclists/Discovery/Web-Content/raft-medium-words.txt \
     -u https://target.example.com/FUZZ \
     -e .php,.bak,.zip,.txt -ac

Virtual host fuzzing. A single IP address often serves multiple sites based on the Host header. By putting FUZZ in that header, you discover host names that are not in DNS. The default site keeps returning the same size, so you filter it out with -fs.

ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt \
     -u https://target.example.com/ \
     -H "Host: FUZZ.target.example.com" -fs 4242

Hidden GET parameters. An endpoint sometimes behaves differently once you send the right parameter. Put FUZZ in the query string and filter out the responses that do not change the response size.

ffuf -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt \
     -u "https://target.example.com/api/item?FUZZ=1" -ac

Testing POST fields. With -X POST and FUZZ in the body (-d) you test form fields. That way you check, for example, which field names produce a response that differs from the standard error message.

ffuf -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt \
     -u https://target.example.com/login \
     -X POST -d "FUZZ=test" \
     -H "Content-Type: application/x-www-form-urlencoded" -ac

Detection and defense

A fuzzing run stands out through its volume. With the default 40 threads ffuf sends thousands of requests per minute from a single IP address, and that leaves a long trail of 404 and 403 lines in the web server logs. A blue team that watches for unusual request counts spots such a scan immediately.

For defenders it comes down to a few measures. A WAF or rate limiter that caps the number of requests per IP slows a fuzzing run down considerably and produces a clear signal. Make sure as well that the application returns a real 404 for a non-existent page instead of a 200, so an attacker cannot filter easily. And the most important thing stays basic hygiene: do not leave backups, .git directories or forgotten admin panels on a production server, because that is exactly what ffuf finds first.

Only use ffuf on systems for which you have explicit, written permission. A fuzzing run generates a lot of traffic, can overload an application and, without an agreed scope, amounts to unauthorized access.

Frequently asked questions about ffuf

What is the difference between ffuf, gobuster and wfuzz?

All three do the same kind of work: replace part of an HTTP request with words from a list and watch how the server responds. The difference is in flexibility and maintenance. With ffuf the FUZZ keyword can go anywhere (URL, header or body), so a single tool handles directories, virtual hosts and parameters alike, and it is actively maintained. Gobuster is roughly as fast but less flexible in where you fuzz. Wfuzz is older, slower and barely maintained anymore. At Hackify, ffuf is our default tool for web fuzzing.

How do you avoid false positives in ffuf?

Sometimes a server returns a 200 OK with the same ’not found’ page for every unknown URL, instead of a proper 404. Then everything looks like a hit. Filter on the characteristics of that default page: -fs on size, -fw on word count or -fl on line count. If you do not know those values, -ac (autocalibration) does it for you: ffuf first sends a few random requests, learns what a non-existent page looks like and filters those out automatically.

Can you fuzz parameters and POST data with ffuf?

Yes. The FUZZ keyword works in the URL, in headers (-H) and in the request body (-d). That lets you test hidden GET parameters (-u 'https://target/?FUZZ=1') or POST fields. For targeted brute-forcing of a login form or exploiting an injection we usually reach for Burp Suite or a dedicated tool, but for discovering existing parameters ffuf is excellent.

How noisy is ffuf and how is it detected?

Very noisy. With the default 40 threads ffuf fires thousands of requests per minute, leaving a pile of 404 or 403 lines in the web server logs from a single IP address. A WAF or rate limiter picks up that pattern without trouble and can block you. If you want to stay under the radar you lower the speed with -t and -p (delay between requests), but the scan stays visible in the logs.

Related articles