Cuando la API confía demasiado en el frontend (II): secuestrando la cuenta del administrador

“Piénsalo ¿Qué pasaría si fuese posible tomar el control de la cuenta de un Administrador web?”
Estas vulnerabilidades ya deberían estar mitigadas en todas las aplicaciones web que utilizamos hoy en día, pero por desgracia, seguimos encontrándolo en muchas auditorías a empresas, obteniendo privilegios de administrador en tan solo unos minutos.
A continuación, explicamos cómo funcionan estas vulnerabilidades para que empresas como la tuya, pueda evitarlo y estar preparado antes posibles ataques.
Haciendo memoria:
En el artículo anterior os contamos cómo, durante una de nuestras auditorías, conseguimos acceder a información de otros usuarios modificando algunos simples identificadores. Para leer el artículo completo clica aquí (aquí hay que meter un enlace para que los que quieran pulsen y los lleve al artículo primero que publicamos).
A modo de resumen y para entenderlo bien:
1_Primero accedíamos a la web y luego iniciábamos sesión:
El usuario inicia sesión
Esta pantalla representa el primer paso del flujo: un usuario legitimo accede al portal con credenciales ficticias y la aplicación recibe un token válido para cargar su perfil.
Hasta este punto todo funciona coma debería: el usuario está autenticado. El fallo no estaba en el login, sino en lo que el backend permitia hacer después con ese token.
Lo que vemos realmente los pentesters por debajo, es de esta forma.
2. Hasta aquí, todo era normal, una vez metíamos las credenciales de usuario válidas, la web nos llevaba al panel típico de nuestro usuario:
CUANDO TODO PARECE CORRECTO
El usuario entra en su perfil Este primer panel representa el comportamiento esperado: un usuario autenticado accede a su área personal y la API devuelve su información de perfil.
◾️Sesión válida
El usuario inicia sesión y la aplicación recibe un token correcto.
◾️Petición GET
El navegador solicita el perfil asociado al identificador del usuario.
◾️Perfil visible
El backend responde y el frontend pinta los datos en pantalla.
A simple vista no hay nada extraño: usuario autenticado, token válido y datos propios. El problema aparece después, cuando se comprueba si ese identificador puede manipularse.
Y lo que nosotros vemos por debajo, es esto:
3. Luego, modificábamos el ID de usuario desde nuestro perfil y conseguíamos acceder a información de otros usuarios, lo cual es un error crítico que no debería ocurrir jamás.
EL MOMENTO CRÍTICO
Cambiamos el ID y apareció otro perfil
Tras confirmar que el usuario autenticado podía cargar su propio perfil, revisamos si el identificador de la petición estaba protegido por autorización en backend.
1_Mismo token
La sesión seguía siendo la de un usuario normal, sin privilegios especiales.
2_ID alterado
Se modifica el identificador del recurso
solicitado dentro de una petición ficticia.
3_ Datos ajenos
La APl responde con información de una cuenta que no pertenece al usuario autenticado.
El fallo no estaba en el login. El usuario tenía un token válido, pero el backend no verificaba si ese token tenía permiso para consultar el perfil solicitado.
Petición legítima vs petición con ID modificado
La visualización muestra el comportamiento esperado frente al comportamiento vulnerable, usando rutas, tokens y datos ficticios.
Qué debería haber ocurrido: aunque el token fuera válido, la API debía comprobar que el usuario autenticado tenía permiso sobre el recurso solicitado. Si el ID no correspondía a su cuenta, la respuesta correcta debía ser un rechazo de autorización, no un perfil ajeno.
Hasta ahí, el impacto ya era grave. Datos personales, direcciones, DNI, correos electrónicos, fotografías de perfil… información suficiente como para generar un problema serio de confidencialidad, cumplimiento normativo y reputación.
“Y ahora viene lo interesante de este nuevo artículo ¿Y si fuera posible realizar otras acciones maliciosas?
Porque una cosa es poder ver información de otros usuarios. Y otra muy distinta es poder tomar el control de sus cuentas. Y eso fue exactamente lo que ocurrió.
4. Primero comprobamos que la plataforma web también nos permitía modificar nuestra propia contraseña sin validación añadida por parte del equipo de IT o con metodologías alternativas de seguridad.
Cambiamos nuestra propia contraseña.
Después de acceder al perfil, comprobamos que la plataforma también permitía modificar la contraseña desde el área privada del usuario autenticado.
En este punto el comportamiento parece legítimo: un usuario normal cambia su propia contraseña. Lo importante para la auditoría era entender cómo viajaba esa acción hacia la API y qué datos utilizaba el servidor para decidir qué cuenta modificar.
1_Sesión válida
El usuario ya está autenticado y dispone de un token correcto.
2_Formulario visible
El frontend muestra una pantalla para actualizar la contraseña.
3_Petición POST
La API recibe el ID del perfil y los nuevos datos de contraseña.
Como siempre, las peticiones que veíamos nosotros por debajo al realizar las acciones en la web eran estas.
“Entonces ¿Podríamos escalar privilegios y tomar el control total de la web?”
Para pentester como nosotros, este momento es uno de los más atractivos. Pero, para la empresa que auditamos es un fallo crítico que afecta directamente a la confianza del sistema.
5. Una vez llegados a este punto, la pregunta era obvia ¿Y si también podemos cambiar la contraseña del usuario Administrador? Y así lo hicimos:
Modificamos la contraseña del administrador.
Partiendo de un usuario convencional, reutilizamos el mismo flujo de cambio de contraseña, pero alterando el identificador enviado a la API para apuntar al usuario administrador.
TOKEN USADO
Bearer token_user_convencional
1_Petición legítima
El usuario normal cambia su propia contraseña con el ID 463.
2_ID modificado
Se cambia el ID de la ruta y también el ID enviado en el cuerpo del POST.
3_Respuesta 200 OK
La API confirma el cambio sobre el usuario administrador objetivo.
Las peticiones modificadas por debajo fueron las siguientes:
Una vez llegados a este punto decidimos finalizar esta parte de la auditoria ya como dicen algunos: “todo el pescado estaba vendido”, y es que el sistema asumía que, si la petición llegaba desde la aplicación, entonces era legítima. Y esa suposición es una de las más peligrosas en seguridad web.
Y ¡NO! El problema no era el botón
Este punto es importante. Muchas veces, cuando se explica este tipo de vulnerabilidad, la primera reacción suele ser:
“Pero el usuario no tiene ese botón en pantalla.”
Y es cierto, puede que el usuario no vea un botón para cambiar la contraseña de otra persona y puede que visualmente todo parezca bien controlado.
Pero la seguridad no puede depender de lo que se ve en pantalla.
Un atacante no necesita que el botón exista, solo necesita que la API acepte la acción.
Y si el backend no valida permisos, roles y contexto en cada petición sensible, el hecho de ocultar opciones en el frontend no sirve como medida de seguridad.
En resumen:
La seguridad no puede depender de lo que el usuario ve. Debe depender de lo que el servidor valida.
- Cada petición sensible debe comprobar permisos, contexto, rol y recurso afectado.
- Porque el frontend muestra y el backend decide.
- ¿Y cuando el backend no decide? Decide el atacante.
En 4Elitech realizamos auditorías web orientadas a descubrir este tipo de riesgos:
- Vulnerabilidades que no siempre aparecen en un escáner, pero que pueden tener un impacto crítico para el negocio.
- Analizamos aplicaciones desde la perspectiva técnica, pero también desde la lógica de abuso:
- Qué puede hacer un usuario
- Qué debería poder hacer y qué ocurre cuando se manipulan los flujos normales de la aplicación.
Porque los fallos más peligrosos no siempre están en lo evidente, a veces, están en una pequeña suposición que nadie cuestionó.
Y nosotros estamos para eso.
