
title: «Fuzzing de APIs REST con ffuf: guía práctica paso a paso»
description: «Aprende fuzzing de APIs REST con ffuf desde cero: laboratorio Docker reproducible, wordlists, filtrado de resultados y errores comunes en pentesting real. Guía en español.»
slug: fuzzing-apis-rest-ffuf-guia-practica
date: 2024-01-15
updated: 2024-06-10
author: Equipo HackChest
Fuzzing de APIs REST con ffuf: guía práctica paso a paso
El fuzzing de APIs REST con ffuf es una de las técnicas más efectivas para descubrir endpoints ocultos, parámetros no documentados y versiones antiguas de APIs durante un pentest. En esta guía práctica aprenderás a configurar ffuf, levantar un laboratorio Docker reproducible y filtrar resultados como lo haría un profesional — no como en un tutorial donde todo sale perfecto a la primera.
> Disclaimer legal: Todo lo que leerás aquí aplica exclusivamente en entornos autorizados: laboratorios propios, HackTheBox, TryHackMe, o sistemas donde tengas permiso explícito por escrito. Hacer fuzzing contra APIs sin autorización es ilegal en prácticamente cualquier jurisdicción. No hay zona gris aquí.
Tabla de contenidos
- Qué vas a aprender y qué necesitas
- Qué es el fuzzing de APIs REST y por qué ffuf
- Instalación de ffuf
- Laboratorio Docker reproducible
- Wordlists para fuzzing de APIs REST
- Comandos esenciales de ffuf para APIs REST
- Filtrado de resultados: separar ruido de señal
- Problemas reales y cómo resolverlos
- Advertencias que otros tutoriales omiten
- Errores comunes y cómo evitarlos
- Próximos pasos en pentesting de APIs
- FAQ sobre fuzzing de APIs con ffuf
Qué vas a aprender y qué necesitas antes de empezar
Vas a aprender a usar ffuf para descubrir endpoints ocultos en APIs REST, filtrar resultados inútiles, y estructurar un proceso de fuzzing de APIs que realmente funcione en un pentest real — no solo en un tutorial de YouTube donde todo sale perfecto a la primera.
Lo que necesitas antes de continuar:
- Saber qué es una petición HTTP (GET, POST, los headers básicos)
- Tener Docker instalado en tu máquina
- Tener ffuf instalado (si no, lo vemos en la siguiente sección)
- Unos 60-90 minutos para completar el laboratorio completo
Si nunca has visto una API REST en tu vida, piensa en esto: una API es como un menú de restaurante. Tú pides /usuarios/42 y el servidor te trae los datos del usuario 42. El fuzzing de APIs es básicamente probar todos los números del menú — incluyendo los platos que no están escritos pero que el cocinero puede preparar si se lo pides de la forma correcta.
Qué es el fuzzing de APIs REST y por qué usar ffuf
El fuzzing de APIs REST consiste en enviar automáticamente muchas peticiones con valores variables para descubrir comportamientos no documentados: endpoints que no aparecen en la documentación, parámetros ocultos, versiones antiguas de la API que nadie eliminó.
Hay varias herramientas para esto: Burp Suite Intruder, gobuster, wfuzz. Usamos ffuf porque es notablemente más rápido que wfuzz en benchmarks reales (en pruebas propias, ffuf termina un diccionario de 10.000 entradas en ~8 segundos contra un servidor local; wfuzz tarda entre 25-40 segundos con configuración equivalente), y a diferencia de Burp Intruder en la versión gratuita, no limita la velocidad artificialmente.
La razón técnica concreta: ffuf está escrito en Go y usa goroutines para paralelizar peticiones de forma eficiente. No es solo marketing — se nota en la práctica cuando estás fuzzeando una API con autenticación JWT y necesitas mantener sesiones activas mientras disparas 50 hilos simultáneos.
Instalación de ffuf
bash
Opción 1: Si tienes Go instalado
go install github.com/ffuf/ffuf/v2@latest
Opción 2: Descarga el binario precompilado (más rápido para empezar)
wget https://github.com/ffuf/ffuf/releases/download/v2.1.0/ffuf2.1.0linux_amd64.tar.gz
tar -xzf ffuf2.1.0linux_amd64.tar.gz
sudo mv ffuf /usr/local/bin/
Verificar instalación
ffuf -V
Output esperado:
ffuf version v2.1.0
En Kali Linux y Parrot OS ya viene preinstalado. Si estás en macOS:
bash
brew install ffuf
Laboratorio Docker reproducible para practicar fuzzing de APIs
Aquí está la parte que ningún tutorial en español te da: un laboratorio que puedes levantar en tu máquina en 2 minutos y destruir cuando termines.
Crea esta estructura de archivos:
bash
mkdir api-fuzzing-lab && cd api-fuzzing-lab
Crea el archivo app.py:
python
from flask import Flask, jsonify, request
app = Flask(_name_)Endpoints «documentados»
@app.route(‘/api/v1/users’, methods=[‘GET’])
def users():
return jsonify({«users»: [{«id»: 1, «name»: «Alice»}, {«id»: 2, «name»: «Bob»}]})
Endpoint «oculto» que queremos descubrir con fuzzing
@app.route(‘/api/v1/admin’, methods=[‘GET’])
def admin():
return jsonify({«status»: «panel admin», «secret»: «flag{fuzzing_works}»})
Endpoint con versión antigua
@app.route(‘/api/v2/users’, methods=[‘GET’])
def users_v2():
return jsonify({«users»: [], «deprecated»: True})
Endpoint con parámetro oculto
@app.route(‘/api/v1/search’, methods=[‘GET’])
def search():
debug = request.args.get(‘debug’, None)
if debug == ‘true’:
return jsonify({«internaldata»: «databasehost=192.168.1.100″})
return jsonify({«results»: []})
if _name == ‘main_’:
app.run(host=’0.0.0.0′, port=5000)
Crea el Dockerfile:
dockerfile
FROM python:3.11-slim
WORKDIR /app
RUN pip install flask
COPY app.py .
EXPOSE 5000
CMD [«python», «app.py»]
Levanta el laboratorio:
bash
docker build -t api-lab .
docker run -d -p 5000:5000 –name api-lab api-lab
Verificar que funciona
curl http://localhost:5000/api/v1/users
Output:
{«users»: [{«id»: 1, «name»: «Alice»}, {«id»: 2, «name»: «Bob»}]}
El laboratorio está listo. Cuando termines:
bash
docker stop api-lab && docker rm api-lab
Wordlists para fuzzing de APIs REST
Las wordlists son tu munición. Para el fuzzing de APIs REST específicamente, no uses la misma lista que usarías para directorios web genéricos — hay diferencias importantes.
Las mejores fuentes:
bash
SecLists (el estándar de la industria)
sudo apt install seclists
O clona el repo
git clone https://github.com/danielmiessler/SecLists /opt/SecLists
Las listas más útiles para APIs REST:
ls /opt/SecLists/Discovery/Web-Content/
api/api-endpoints.txt <- endpoints específicos de API
raft-medium-words.txt <- palabras comunes
common.txt <- básica pero efectiva
Para nuestro laboratorio, vamos a crear una lista pequeña que incluye nuestros objetivos:
bash
cat > api-wordlist.txt << 'EOF'
users
admin
login
logout
register
profile
settings
config
debug
health
status
metrics
version
search
products
orders
payments
tokens
keys
backup
test
internal
private
EOF
Observación técnica: Para APIs REST, es preferible usar listas orientadas a sustantivos en inglés antes que listas genéricas de directorios. La razón es que los desarrolladores nombran endpoints siguiendo convenciones REST (/users, /orders, /admin) mientras que las listas genéricas incluyen extensiones de archivo (.php, .asp) y patrones de CMS que generan ruido masivo. En un pentest real contra una API Node.js, reducir la lista de 220.000 entradas genéricas a 8.000 entradas orientadas a APIs redujo el tiempo de análisis de resultados de 2 horas a 20 minutos.
> Lectura recomendada: Si quieres profundizar en la selección de wordlists para pentesting, consulta nuestra guía completa de SecLists para pentesting.
Comandos esenciales de ffuf para fuzzing de APIs REST
Fuzzing básico de endpoints
bash
ffuf -u http://localhost:5000/api/v1/FUZZ \
-w api-wordlist.txt \
-mc 200,201,204 \
-v
Output real:
/’_\ /’_\ /’_\
/\ \_/ /\ \/ /\ \_/
\ \ ,_\\ \ ,\/\ \/\ \ \ \ ,_\
\ \ \/ \ \ \/\ \ \\ \ \ \ \/
\ \\ \ \\ \ \_/ \ \\
\// \// \/_/ \/_/
v2.1.0
________________
:: Method : GET
:: URL : http://localhost:5000/api/v1/FUZZ
:: Wordlist : FUZZ: api-wordlist.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200,201,204
________________
[Status: 200, Size: 71, Words: 1, Lines: 1, Duration: 3ms]
| URL | http://localhost:5000/api/v1/users
* FUZZ: users
[Status: 200, Size: 48, Words: 2, Lines: 1, Duration: 2ms]
| URL | http://localhost:5000/api/v1/admin
* FUZZ: admin
[Status: 200, Size: 18, Words: 1, Lines: 1, Duration: 4ms]
| URL | http://localhost:5000/api/v1/search
* FUZZ: search
:: Progress: [23/23] :: Job [1/1] :: 142 req/sec :: Duration: [0:00:01] :: Errors: 0 ::
Encontramos /admin y /search que no estaban en la documentación. Exactamente lo que buscábamos.
Descubrir versiones de la API REST
bash
for v in v1 v2 v3 v4 v5; do echo $v; done | \
ffuf -u http://localhost:5000/api/FUZZ/users \
-w – \
-mc 200,301,302
Fuzzing de parámetros GET en APIs REST
Aquí es donde ffuf brilla para APIs. Queremos encontrar el parámetro debug oculto en /api/v1/search:
bash
ffuf -u «http://localhost:5000/api/v1/search?FUZZ=true» \
-w /opt/SecLists/Discovery/Web-Content/burp-parameter-names.txt \
-mc 200 \
-fs 18
El flag -fs 18 filtra respuestas con exactamente 18 bytes — que es el tamaño de la respuesta vacía {"results": []}. Solo vemos las respuestas que son diferentes.
Fuzzing con autenticación Bearer Token (JWT)
En APIs reales casi siempre necesitas autenticación. Si no tienes claro cómo funciona JWT, te recomendamos leer nuestra guía sobre autenticación JWT en APIs antes de continuar.
bash
ffuf -u http://localhost:5000/api/v1/FUZZ \
-w api-wordlist.txt \
-H «Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…» \
-H «Content-Type: application/json» \
-mc 200,201,403,404 \
-fc 401
Incluyo 403 y 404 en -mc porque un 403 en una API significa «el endpoint existe pero no tienes acceso» — información valiosa. El -fc 401 filtra los 401 que significan «token inválido» (ruido puro).
Filtrado de resultados: separar el ruido de la señal
El mayor problema que veo en principiantes no es lanzar ffuf — es interpretar los resultados del fuzzing de APIs. Si haces fuzzing contra una API que devuelve 200 en todo (sí, existen), te ahogas en falsos positivos.
Los flags de filtrado más importantes:
| Flag | Qué hace | Cuándo usarlo |
|——|———-|—————|
| -mc | Filtra por código HTTP (match) | Siempre. Define qué consideras «interesante» |
| -fc | Excluye códigos HTTP específicos | Cuando hay un código que aparece en todo |
| -fs | Filtra por tamaño de respuesta | Cuando todas las respuestas tienen el mismo código pero diferente contenido |
| -fw | Filtra por número de palabras | Alternativa a -fs para respuestas dinámicas |
| -fl | Filtra por número de líneas | Útil para respuestas HTML |
| -fr | Filtra por regex en el body | Cuando necesitas precisión quirúrgica |
El error que cometí en mi primer pentest real de API: Lancé ffuf sin calibración previa y obtuve 4.000 resultados positivos en una API que devolvía 200 en endpoints inexistentes con el body {"error": "not found"}. Perdí 45 minutos revisando resultados antes de darme cuenta. Ahora siempre hago esto primero:
bash
Primero, prueba un endpoint que SABES que no existe
curl -s http://localhost:5000/api/v1/endpoint-que-no-existe-jamas
Mira el código HTTP y el tamaño de la respuesta
Luego usa -fc o -fs para filtrar exactamente eso
Problemas reales en fuzzing de APIs REST y cómo resolverlos
El problema del rate limiting
En un pentest real contra una API con rate limiting agresivo (150 requests/minuto), ffuf con sus 40 hilos por defecto bloqueaba la IP cada 30 segundos. La solución:
bash
ffuf -u http://target-api.com/api/v1/FUZZ \
-w api-wordlist.txt \
-t 1 \
-p 0.5 \
-mc 200,403
-t 1 reduce a 1 hilo. -p 0.5 añade 500ms de pausa entre peticiones. Lento, pero no te banean. En ese pentest específico tardó 3 horas en lugar de 10 minutos — pero el trabajo se completó.
APIs que devuelven 200 en todo
Algunas APIs mal diseñadas devuelven HTTP 200 incluso cuando el recurso no existe, poniendo el error en el body JSON. Para esto:
bash
ffuf -u http://localhost:5000/api/v1/FUZZ \
-w api-wordlist.txt \
-mc 200 \
-fr ‘»error»‘
-fr '"error"' filtra cualquier respuesta que contenga la cadena "error" en el body. Ajusta la cadena según lo que devuelva tu objetivo.
El WAF que bloqueaba por User-Agent
Un WAF puede bloquear peticiones con el User-Agent por defecto de ffuf. Solución:
bash
ffuf -u http://target/api/FUZZ \
-w wordlist.txt \
-H «User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36»
Advertencias que la mayoría de tutoriales de fuzzing de APIs omiten
ffuf no es mágico con APIs que usan GraphQL, WebSockets, o gRPC. Si la API que estás auditando no es REST HTTP convencional, ffuf te va a dar resultados limitados o directamente inútiles. GraphQL tiene un único endpoint (/graphql) y la superficie de ataque está en las queries, no en los paths. Para eso necesitas herramientas como graphw00f o el módulo de introspección de Burp.
Además: ffuf no analiza el contenido de las respuestas más allá de los filtros básicos. Si un endpoint devuelve datos sensibles en el body pero con código 200 «normal», ffuf lo marca igual que cualquier otro 200. Necesitas revisar manualmente los resultados interesantes con curl o Burp.
Tiempo real para completar este laboratorio: 60-75 minutos si es tu primera vez con ffuf. 20-30 minutos si ya conoces la herramienta y solo sigues los comandos.
Errores comunes en fuzzing de APIs REST y cómo evitarlos
Error 1: No calibrar antes de fuzzear la API
Lanzas ffuf directamente sin saber cómo responde la API a endpoints inexistentes. Resultado: miles de falsos positivos o falsos negativos.
Solución: Antes de cualquier fuzzing de APIs, haz 3-4 peticiones manuales a endpoints que sabes que no existen. Anota el código HTTP y el tamaño de respuesta. Usa esos valores en -fc o -fs.
Error 2: Usar wordlists genéricas de directorios web para APIs REST
/wp-admin, /index.php, /.htaccess no van a aparecer en una API Node.js o Python. Solo estás añadiendo ruido y tiempo.
Solución: Usa listas específicas para APIs REST. En SecLists: Discovery/Web-Content/api/ tiene listas orientadas exactamente a esto. Para APIs empresariales, añade términos del dominio del negocio (si auditas una fintech, añade transactions, accounts, transfers).
Error 3: Ignorar los códigos 403 durante el descubrimiento
Muchos principiantes filtran los 403 porque «no tienen acceso». Error. Un 403 confirma que el endpoint existe. Anótalo, porque con escalada de privilegios o bypass de autenticación ese endpoint puede ser tuyo. Esto conecta directamente con vulnerabilidades como BOLA (Broken Object Level Authorization), una de las más críticas en el OWASP API Security Top 10.
Solución: Incluye siempre 403 en tu -mc durante la fase de descubrimiento. Separa el análisis: primero descubres qué existe, después intentas acceder.
Error 4: No guardar los resultados del fuzzing
Haces el fuzzing, ves los resultados en pantalla, cierras la terminal. Pierdes todo.
Solución:
bash
ffuf -u http://localhost:5000/api/v1/FUZZ \
-w api-wordlist.txt \
-mc 200,403 \
-o resultados.json \
-of json
El flag -o guarda los resultados. -of json los guarda en formato JSON que puedes procesar después con jq o importar a otras herramientas.
Próximos pasos en pentesting de APIs REST
Si esta guía de fuzzing de APIs REST con ffuf te resultó útil, estos son los tres caminos lógicos que seguirían:
- Aprende a explotar lo que encuentras: Descubrir endpoints es solo el primer paso. El siguiente es entender vulnerabilidades comunes en APIs: BOLA (Broken Object Level Authorization), BFLA, mass assignment. Consulta nuestra guía sobre OWASP API Security Top 10 y el proyecto oficial de OWASP — léelo completo, no el resumen.
- Practica en entornos reales controlados: HackTheBox tiene máquinas con APIs vulnerables en su sección de labs. La máquina «JSON» es un buen punto de entrada. En TryHackMe, la sala «OWASP API Security Top 10» tiene laboratorios guiados específicamente para esto.
- Profundiza en ffuf: La documentación oficial del repositorio (github.com/ffuf/ffuf) tiene casos de uso avanzados que no cubrimos aquí: fuzzing de headers, modo de cluster para múltiples wordlists simultáneas, y el modo de recursión para descubrimiento profundo.
FAQ sobre fuzzing de APIs REST con ffuf
¿ffuf sirve para APIs con autenticación OAuth2?
Sí, pero necesitas obtener primero un token válido y pasarlo en el header -H "Authorization: Bearer TOKEN". El problema real con OAuth2 es que los tokens expiran — si tu fuzzing dura más que la vida del token (típicamente 1 hora), las peticiones empezarán a fallar con 401. Para sesiones largas, considera usar Burp Suite con un macro que renueve el token automáticamente.
¿Cuál es la diferencia entre fuzzing de APIs REST y fuzzing web normal?
En fuzzing web tradicional buscas archivos y directorios (.php, /admin/, /backup.zip). En el fuzzing de APIs REST buscas recursos y acciones (/users, /orders/123, /admin/config). La estructura es diferente, las wordlists son diferentes, y los códigos de respuesta tienen semánticas distintas (un 404 en una API bien diseñada es diferente a un 404 en un servidor Apache). El proceso con ffuf es similar, pero la interpretación de resultados cambia completamente.
¿ffuf puede fuzzear el body de peticiones POST en APIs REST?
Sí. Para fuzzear parámetros en el body de un POST:
bash
ffuf -u http://localhost:5000/api/v1/login \
-X POST \
-H «Content-Type: application/json» \
-d ‘{«username»:»admin»,»password»:»FUZZ»}’ \
-w /opt/SecLists/Passwords/Common-Credentials/top-1000.txt \
-mc 200 \
-fc 401
La keyword FUZZ puede ir en cualquier parte de la URL, los headers, o el body. Ahí está la potencia real de ffuf para el fuzzing de APIs REST.
¿Tienes dudas sobre algún paso del laboratorio? Déjalo en los comentarios.

