API Testing basado en OWASP
Tags: api, testing, owasp, security
Published: 2021-05-17 18:46:58

En [API Testing y no morir en el intento](https://dev.to/atejedaautomation/api-testing-y-no-morir-en-el-intento-1n35) 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](https://github.com/OWASP/API-Security/raw/master/2019/en/dist/owasp-api-security-top-10.pdf) 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 :)](https://www.buymeacoffee.com/To3Dd6m)