Demostración en vídeo del post
En un post anterior se ha descrito el proyecto OWASP Api Security Project el cual se ha publicado en el año 2019 y que describe las principales vulnerabilidades que afectan a las APIs Rest, las cuales después de todo, no dejan de ser aplicaciones web con algunas características particulares. Si quieres aprender en detalle cómo detectar y explotar las principales vulnerabilidades que afectan a las APIs Rest, te recomiendo el curso de Hacking web contra APIs Rest disponible en THW.
Concretamente, la vulnerabilidad de «asignación masiva» o «mass assignment» se encuentra en la posición 6 de la lista y en el proyecto tiene la siguiente descripción:
Vincular los datos proporcionados por el cliente (por ejemplo, en formato JSON) a los modelos de datos en el servidor, sin realizar el filtrado de propiedades adecuado, generalmente conduce a una asignación masiva. Ya sea adivinando las propiedades de los objetos, explorando otros puntos finales de la API, leyendo la documentación o proporcionando propiedades de objetos adicionales en los payloads de las solicitudes, permite al atacantes modificar las propiedades de los objetos que se supone que no debería poder modificar.
Esta descripción significa que el atacante debe tener un conocimiento sobre cómo se asignan los valores enviados en una estructura en formato JSON (o otro formato) a un objeto en el lado del servidor, ya sea por medio de prueba y error o analizando las respuestas que va devolviendo la API Rest. En cualquier caso, es una vulnerabilidad con efectos muy dañinos para la aplicación, ya que puede producir desde un defacement o alteraciones en la estructura de las páginas, hasta elevación de privilegios horizontal o vertical. Aunque es una vulnerabilidad critica, no hay que olvidar que el atacante debe tener saber cómo se realiza la asignación en el backend, lo cual no siempre es tan fácil y precisamente por este motivo, es una vulnerabilidad que no se encuentra en las primeras posiciones de la lista.
Como se ha mencionado anteriormente, en un contexto de caja negra se requiere prueba y error para conseguir el objetivo, es necesario analizar las respuestas emitidas por la aplicación y comprobar si se expone algún atributo que pueda ser susceptible de asignación masiva. En un modelo de caja blanca o gris encontrar este tipo de vulnerabilidades normalmente implica menor esfuerzo, ya que se cuenta con el código fuente de la aplicación y esto ayuda a detectar el defecto mucho más fácilmente. Para realizar algunas pruebas, se puede utilizar una API Rest vulnerable por diseño, existe una buena cantidad de estas aplicaciones en GitHub, sin embargo para este caso se utilizará DVWS (Damn Vulnerable Web Services). Se trata de una aplicación desarrollada en NodeJS y que se encuentra «dockerizada». Solamente hace falta tener instalado Docker y docker-compose y levantar los contenedores.
Aunque se trata de una aplicación que tiene múltiples vulnerabilidades, en este caso se probará la asignación masiva que permite la elevación de privilegios de una forma fácil y rápida, así quedará mucho más claro su impacto.
En primer lugar, se puede apreciar que existe una interfaz web en la que desde el mismo formulario se puede ejecutar el proceso de registro de usuarios y autenticación. No hay que olvidar que es una aplicación de pruebas, es normal que su apariencia y funcionamiento sea poco profesional.
Utilizando una herramienta como Burp o ZAP se pueden capturar ambas peticiones y verificar los campos que devuelve la API Rest en la respuesta. Primero, la petición de registro para poder acceder a la aplicación web.
Se puede apreciar en la respuesta que el código de estado es un HTTP 201, lo que significa que se ha registrado correctamente el usuario. Además, se puede comprobar en la respuesta que la API devuelve el nombre del usuario y el hash de la contraseña. Esto ya representa un problema, si se piensa detenidamente, no hace falta devolverle al cliente dicho hash, basta con indicar que el proceso de registro se ha llevado correctamente. Esto puede verse como una fuga de información, sin embargo de momento no parece que haya una vulnerabilidad de asignación masiva. A continuación, se captura la petición de login, en donde se utilizará el usuario que se ha registrado anteriormente.
Esta respuesta es mucho más interesante, ya que se aprecia una estructura JSON completa, en la que aparecen algunos campos que no estaban antes en el proceso de registro. Llama la atención especialmente el campo «admin», el cual al parecer recibe un valor booleano. Cuando se encuentra algo así, cabe preguntarse ¿Qué pasaría si durante el proceso de registro del usuario envío el campo «admin» con el valor «true»? es una observación simple y se produce por la sospecha de que es un campo que tiene un valor false por defecto y que, posiblemente, se encuentra en el modelo de datos. Si se envía dicho campo en la petición y la aplicación simplemente deserializa la estructura JSON en un objeto en servidor sin hacer ninguna validación, se producirá la asignación masiva.
Y ahora, para comprobar si lo que se sospecha es correcto, basta simplemente con iniciar sesión y comprobar si el usuario tiene permisos de administrador.
Como se puede ver, ahora el usuario «testuser» tiene privilegios de administrador y tendrá la posibilidad de acceder a la consola administrativa de la aplicación web.
En conclusión, se trata de una vulnerabilidad en la que hace falta estar atento a los detalles y contar con experiencia en pentesting web. En una API rest con cientos de endpoints no será tan sencillo como se ha visto en este post (o sí), pero lo que se pretende es que quede claro el concepto para que luego lo tengas en cuenta y puedas realizar estas pruebas en las auditorías web que realizas. Finalmente, si estás interesado en aprender en detalle las vulnerabilidades del OWASP API Security Project y el uso de ZAP para detectar y explotar dichos defectos, te recomiendo apuntarte al curso completo de ZAP y al de Hacking contra APIs Rest.
Un saludo y Happy Hack!
Adastra.