DEV Community

loading...
Cover image for API Testing basado en OWASP

API Testing basado en OWASP

Alfred Tejeda
Functional & Automation tester | Testing writer | Automation consultant
・4 min read

En API Testing y no morir en el intento realicé una introducción sobre qué deberíamos de probar en una API, en esta oportunidad vamos a tomar en consideración el top 10 de OWASP para que agreguemos casos de pruebas de introducción a seguridad.
Para que la lectura no sea tan larga, he decidido abarcar 2 puntos por post.

OWASP (Open Web Application Security Project), es un proyecto sin ánimo de lucro a nivel mundial que busca mejorar la seguridad del software en general. Para esto, la organización se ha provisto de una serie de herramientos y documentos que explican cuáles son las brechas de seguridad más comunes en cualquier sistema de información. Sobra decir, que todos los materiales de OWASP están disponibles de manera libre (gratuita) para su libre consulta y uso.

1. Autorización segura a nivel de objeto:

Las API suelen procesar sus funcionalidades a través del uso de identificadores de objetos.
Supongamos que tenemos un endpoint al que se le indica el número de documento que queremos acceder:

method endpoint result
GET /document/2000 200 OK
GET /document/2001 200 OK
GET /document/1999 404 Not Found

Podemos evidenciar que el número de documento es un valor consecutivo, por lo que un atacante puede intentar acceder a estos documentos o saber cuales se encuentra disponibles o no. Para este punto que estamos tratando como QAs (debemos ser preventivos, según definición) podemos recomendar al equipo de desarrollo que el número de documento se encuentre cifrado y podemos crear un caso de prueba que evalue que al colocar un valor no cifrado este retorne error , por lo que al ejecutar nuestras pruebas podríamos tener el siguiente resultado:

method endpoint result
GET /document/2000 400 Bad Request
GET /document/08f90c1a417155361a5c4b8d297e0d78 200 OK
GET /document/1999 400 Bad Request

2. Autenticación insegura

Los mecanismos de autenticación a menudo se implementan de manera incorrecta, permitiendo a los atacantes comprometer los tokens de autenticación o explotar las fallas de implementación para asumir las identidades de otros usuarios temporal o permanentemente. Comprometer la capacidad del sistema para identificar al cliente / usuario, compromete la seguridad de la API en general. Pero, ¿Esto a qué hace referencia?. Veamos:
Un usuario (puede ser atacante o no) intenta realizar un inicio de sesión exitoso:

method endpoint result
POST /login user / password1 Contraseña incorrecta 403 Forbidden
POST /login user / password2 Contraseña incorrecta 403 Forbidden
POST /login user / passwordN Contraseña incorrecta 403 Forbidden
POST /login user / password1000 Autenticado 200 OK

Podemos evidenciar que luego de mil intentos pudo acceder, pero se debería permitir tantos intentos, la recomendación que debemos dar es establecer un límite de intentos ya sea para suspender y/o bloquear la cuenta. En mi experiencia he visto que para evitar esta autenticación insegura se establece un límite de 3 intentos para suspensión y luego 6 para bloqueo, por otra parte he visto un límite de 3 intentos por día para suspensión, 6 intentos (entre 2 días) bloqueo preventivo y 9 intentos (entre 3 días) bloqueo definitivo. Esto por su puesto va anclado al tipo de negocio, pero la finalidad es la misma: ¡Establecer límites de intentos! Así nuestros casos de prueba se basarían en probar estos límites:

method endpoint result
POST /login user / password1 Contraseña incorrecta 403 Forbidden
POST /login user / password2 Contraseña incorrecta, queda 1 intento 403 Forbidden
POST /login user / passwordN Contraseña incorrecta 403 Forbidden

Otro escenario dónde los procesos de autenticación son inseguros puede ser el siguiente, el usuario (atacante o no) desea conocer si un correo se encuentra registrado o no, para ello utiliza la opción de recuperar contraseña. Veamos:

method endpoint result
POST /password_recovey usuario1@yopmail.com El usuario no existe 200 OK
POST /password_recovey usuario2@yopmail.com El usuario no existe 200 OK
POST /password_recovey usuarioN@yopmail.com El usuario no existe 200 OK
POST /password_recovey usuario100@yopmail.com Se enviaron las instrucciones al correo 200 OK

Acá podemos evidenciar que el sistema está indicando si el correo existe o no, por lo que le estamos dando la respuesta que el atacante esperaba. Cómo sugerencia podemos indicar que la respuesta del servicio pueda ser "Se enviaron las instrucciones al correo" aún si el correo existe o no, de esta forma si un atacante realiza 1000 peticiones en las que todas respondan OK, entonces tendrá que tomar más tiempo para comprobar si en efecto el correo existe o no:

method endpoint result
POST /password_recovery usuario1@yopmail.com Se enviaron las instrucciones al correo 200 OK
POST /password_recovery usuario2@yopmail.com Se enviaron las instrucciones al correo 200 OK
POST /password_recovery usuarioN@yopmail.com Se enviaron las instrucciones al correo 200 OK
POST /password_recovery usuario1000@yopmail.com Se enviaron
las instrucciones al correo 200 OK

Se puede sugerir alguna estrategia, una no muy común pero si efectiva que he visto en mi trayecto es enviar un mensaje indicando que ha ocurrido un error en específico pero el mensaje si es enviado en caso de coincidir coincidencia.

Hasta este punto hemos visto 2 de los 10 puntos que OWASP nos menciona, tomando en consideración estos 2 puntos ya podemos ir creando casos de prueba que cumplan con requirimientos básicos de seguridad. En la próxima entrada hablaremos de la "Exposición excesiva de datos" y la "Falta de recursos y límites de uso".

Puedes dejarme en los comentarios, que estrategias aplican en tu corporación y que casos de prueba crees que puedan llegar a ser o sean imprescindible para evitar estos puntos

Me gusta escribir sobre testing en general, gracias a esto me doy cuenta de lo que me falta por aprender, también me encanta el café, por si deseas regalarme uno :)

Discussion (0)