Manual de Burp Suite Community Edition
Capítulo 13 · Direcciones y datos personales
Serie: Burp Suite desde cero | unfantasmaenelsistema.com
El capítulo 6 ya señaló las direcciones como el candidato número uno a IDOR (Insecure Direct Object Reference) en cualquier aplicación con más de un usuario, y avisó de que le dedicaríamos un capítulo entero. Ha llegado el momento -pero esta vez con dos cuentas reales, alumno.ghostacademy@example.com (cliente normal, de los capítulos 11 y 12) y la cuenta admin creada por mass assignment en el capítulo anterior. Con dos identidades de verdad, cazar un IDOR deja de ser teoría.
Qué aprenderás en este capítulo
Qué es exactamente un IDOR y cómo probarlo de forma sistemática con dos cuentas · Que /api/Addresss/{id} SÍ está protegido -un contraejemplo tan útil como un caso vulnerable · El IDOR real de esta sesión: /api/Users/{id} filtra el email y el rol de cualquier usuario a cualquier cuenta logueada · Por qué la interfaz nunca te iba a avisar de que este endpoint existía · La diferencia entre autenticación y autorización, que es donde vive todo este capítulo
La cuenta alumno tiene una dirección guardada desde el capítulo 11 -id 7, ligada a su UserId (25). Pedirla con el propio token de esa cuenta es, como cabría esperar, un 200 sin sorpresas:

GET /api/Addresss/7 con el token de alumno.ghostacademy: 200 OK, su propia dirección
La prueba de un IDOR es siempre la misma, con cualquier objeto: repetir la petición exacta, cambiando solo una cosa -la identidad de quien pregunta- y comprobar si la respuesta cambia de forma coherente con esa identidad, o si el servidor sigue entregando el mismo objeto sin comprobar nada.
Se manda la misma petición a Repeater y se cambia solo la cabecera Authorization por el token de la cuenta admin -que no tiene ninguna relación con esa dirección. El id de la URL no cambia, solo quién pregunta:

Misma URL, token de otra cuenta: 400 Bad Request, "Malicious activity detected."
No todo lo que se prueba está roto -y eso también hay que documentarlo
Juice Shop sí comprueba, en este endpoint, que la dirección solicitada pertenece a quien hace la petición -y en vez de devolver un 403 discreto, responde con un mensaje que deja claro que ha detectado el intento. Es un endpoint bien protegido, y conviene saber reconocerlo tan bien como se reconoce uno vulnerable: un pentest que solo reporta fallos, sin verificar también qué está bien hecho, deja a quien lo lee sin saber si un área quedó sin probar o si de verdad está segura.
El capítulo 12 dejó una pista sin explotar: la respuesta del registro reveló campos internos del modelo de usuario -id, role, email- que nunca aparecen en ningún formulario. Si esos campos existen, ¿responde también un GET directo por id? Se prueba con el token de la cuenta alumno -un cliente normal, sin ningún privilegio- contra el id 1, que en cualquier instalación de Juice Shop pertenece a la cuenta administradora:

GET /api/Users/1 con el token de un cliente normal: 200 OK, con el email y el role:"admin" de otra cuenta
Esto es un IDOR de manual
No hace falta ser administrador para leerlo -basta con estar logueado, con cualquier cuenta. El servidor comprueba que existe un token válido (autenticación), pero no comprueba si esa cuenta tiene permiso para ver ESE usuario en concreto (autorización). Esa es la definición exacta de un IDOR: una referencia directa a un objeto interno -aquí, un id numérico de usuario- que se resuelve sin verificar la relación entre quien pregunta y el objeto pedido.
Y no hace falta pararse en un solo id. El mismo modelo tiene un endpoint de listado que devuelve todos los registros de golpe, con el mismo control de acceso -es decir, con ninguno:

GET /api/Users/ con el mismo token de cliente normal: la lista completa de usuarios registrados, 7.523 bytes de un solo tirón
Esto es precisamente lo que el capítulo 8 preparó sin saberlo: automatizar con Intruder un recorrido de ids del 1 al 100 sobre /api/Users/{id} convertiría este hallazgo puntual en una lista completa de correos electrónicos y roles de cada persona registrada en la tienda -material de sobra para una campaña de phishing dirigida, o para saber exactamente qué cuentas merece la pena atacar primero por tener privilegios.
Nada de esto se ve navegando. La cuenta alumno es, para la interfaz, un cliente cualquiera -sin ningún enlace, botón ni pantalla que sugiera que este endpoint existe:

El menú de cuenta de un cliente normal: Orders & Payment, Privacy & Security, Logout -ninguna pista de administración
IDOR vive en la API, no en los botones
Este es quizás el ejemplo más claro de todo el manual de por qué auditar una aplicación significa auditar sus peticiones, no su interfaz. Nadie diseñó un botón para leer /api/Users/1 -la vulnerabilidad no está en lo que la aplicación muestra, sino en lo que su API acepta sin comprobar. Si esta sesión se hubiera limitado a clicar por la SPA, este fallo jamás habría aparecido; solo salió a la luz por probar directamente el mismo endpoint que la sección de administración usa de forma legítima, con una identidad distinta a la que ese endpoint espera.
Un mismo patrón de prueba -repetir la petición cambiando solo la identidad- dio dos resultados opuestos con dos endpoints hermanos: /api/Addresss/{id} comprueba la propiedad del objeto y bloquea el intento; /api/Users/{id} no comprueba nada más allá de que exista un token válido, y filtra a cualquiera el directorio completo de la tienda.
El capítulo siguiente sigue en el terreno de los datos de cuenta, pero cambia de ángulo: recuperación de contraseña y verificación -otro flujo clásico donde la pregunta de seguridad y el código de restablecimiento son, con demasiada frecuencia, más fáciles de adivinar de lo que su diseño pretendía.
unfantasmaenelsistema.com | Seguridad, sistemas y todo lo que no debería funcionar (pero funciona)