lunes, 19 de julio de 2021

API Testing, preparando un buen análisis

Cuando nos disponemos a auditar un sitio web tenemos claro lo que vamos a encontrarnos menú, opciones, formularios, cuadros de búsqueda y mucho texto, sin embargo, cuando vamos a auditar una API, debemos comprender varios puntos esenciales con el objetivo de realizar una auditoría con una adecuada metodología.

¿Qué es una API?

Se trata de un conjunto de definiciones y protocolos que se utilizan para desarrollar e integrar el software de las aplicaciones permitiendo la comunicación entre dos aplicaciones a través de un conjunto de reglas, es decir la especificación formal que establece cómo un módulo de un software se comunica o interactúa con otro.

Imaginemos que nuestra organización tiene la necesidad de crear un aplicativo de movilidad como Uber o una tienda online. ¿Te imaginas que costoso sería en tiempo y recursos el desarrollo de algunos recursos desde cero? Por eso es mejor utilizar un servicio que ya existe como Google Maps o PayPal.
Ese es el concepto de API, no rehacer el trabajo que ya han hecho otros y así poder crear un aplicativo más potente que el resto.

Además, cuando tenemos la necesidad de crear un aplicativo multiplataforma, como aplicaciones móviles tanto para iOS como para Android incluso para tablets como padOS o aplicativos webs surge la necesidad de compartir el Backend entre dichos aplicativos y ahí también aparece la definición de API.


Tipos de API

Existen miles de aplicaciones diferentes y podemos llegar a preguntarnos ¿cómo se han estandarizado las API? La respuesta es que no hay un estándar universal, pero sí que hay una serie de aspirantes que predominan.

Dichos protocolos son REST y SOAP.

  • SOAP: Protocolo Simple de Acceso a Objetos era el favorito indiscutible hasta hace poco. Es un protocolo que nos permite realizar servicios web sin estado, a través de TCP y con un formato XML.
  • REST: Transferencia de Estado Representacional es el recién llegado a los protocolos de servicio web y ya compone más del 70% de las API de hoy en día. Además, admite un mayor número de formatos de datos como XML, JSON e incluso Texto Plano, y ofrece un mejor rendimiento y menor tiempo de carga.

SOAP   REST
Protocolo   Arquitectura
Ancho de banda elevado   Mínimo ancho de banda
Funciona solo en XML   Funciona con XML, JSON y HTML
Soporta protocolos HTTP y SMTP   Solo requiere HTTP
No puede utilizar REST   Si puede utilizar SOAP

¿Cómo funcionan las API REST?

A la hora de interaccionar con una API deberemos saber su funcionamiento básico, este funcionamiento lo podríamos dividir entre códigos de estado y métodos HTTP.

Cuando solicitamos información, el servidor, éste responde con códigos de estado con los que podemos saber el estado de nuestra petición. A continuación, se describen dichos códigos:

  • 2xx: Indican que la petición se ha procesado correctamente.
  • 3xx: Indican redirecciones, se deberá realizar una acción adicional para completar la petición.
  • 4xx: Solicitud inválida, peticiones a recursos inexistentes o no autorizados.
  • 5xx: Indican errores directos del servidor.

Los métodos HTTP permiten interacción con la información de la API, es equivalente al CRUD de las bases de datos.

  • GET: Solicitar información
  • POST: Enviar nueva información, como por ejemplo el registro de una nueva cuenta.
  • PUT: Actualiza un recurso existente, como cambiar contraseña de una cuenta.
  • DELETE: Elimina un recurso.

Autenticación

Mantener una protección y control de la información es crucial para mantener una seguridad mínima en los aplicativos y sistemas, por eso las API tampoco se eximen de mantener una autenticación.
Los cuatro métodos principales de autenticación en API REST son:

  • Autenticación básica:

Es la forma más sencilla de implementar una autenticación en la API. Se basa en un usuario y contraseña para la identificación y se transmiten encodeadeadas en Base64 en la cabecera HTTP Authorization.

Al tratarse de un encodeado simple como Base64, cualquiera que intercepte la transmisión de datos podrá decodificarlo fácilmente. Por lo que la autenticación básica es vulnerable a ataques de Man-In-The-Middle (MiTM) y se considera insegura.

  • Autenticación basada en token:

Al igual que en la autenticación básica, el usuario se identifica con sus credenciales, pero el servidor le generará un token. El servidor guarda en su base de datos el token asociado al usuario para que a partir del momento de la autenticación el usuario no mande más las credenciales por el canal HTTP y mande el token en su lugar.

Por norma general, los tokens están codificados con la fecha y la hora para que en caso de que alguien intercepte el token con un ataque MiTM, no pueda utilizarlo pasado un tiempo establecido. Además de que el token se puede configurar para que caduque después de un tiempo definido, por lo que los usuarios deberán iniciar sesión de nuevo.

JWT (JSON Web Token) es un ejemplo de token utilizado por las APIs, donde se trata de una cadena de texto formada por 3 partes codificadas en Base64 cada una de ellas separada por un punto. JWT es un mecanismo para poder propagar entre dos partes, y de forma segura, la identidad de un determinado usuario, además con una serie de "claims" o privilegios.

  • Autenticación basada en API key:

Para la realización de la autenticación basada en API key primero se deberá configurar el acceso a los recursos de la API. El sistema deberá generar una clave (key) y un secret key para cada cliente que requiera acceso a los servicios. Cada vez que un usuario requiera los servicios de la API se deberá enviar la key y la secret key al servidor.

Este sistema es más seguro que los métodos anteriores, pero la generación de credenciales debe ser manual y esto dificulta la escalabilidad de la API.

  • Autorización abierta (OAuth 2.0):

La automatización a la hora de generación e intercambio de keys en la autenticación basada en API keys fue una de las razones principales por las que se desarrolló el protocolo OAuth.

OAuth 2.0 es un método de autorización utilizado por grandes compañías como Google, Twitter, Amazon, etc, que tiene como propósito permitir a otros proveedores, servicios o aplicaciones, el acceso a información sin facilitar directamente las credenciales de los usuarios.

Un ejemplo de OAuth sería la de un videojuego en un dispositivo móvil Android. En el momento que necesitamos guardar la partida una de las opciones sería utilizar Google Play Games o incluso Facebook. La necesidad de este protocolo surgió con la finalidad de evitar dar las credenciales de nuestros perfiles de Google o Facebook a un tercero como sería el videojuego.

Auditar una API

Al igual que en un pentest podemos enfocarlo de diversas formas, caja negra, caja gris y caja blanca.

Al no tratarse de una web tradicional y no tener formularios, botones o enlaces que interaccionan entre los componentes del backend de la aplicación deberemos encontrar los endpoint, métodos y parámetros de una forma muy tediosa y manual.

El enfoque de una auditoría API en forma de caja negra, es decir sin tener conocimiento alguno de la API excepto la URL, podríamos decir que no sería un enfoque totalmente acertado ya que los auditores disponen de un tiempo limitado y descubrir endpoints, métodos y parámetros es costoso en tiempo y muchas veces no acaba en éxito, ya que se está utilizando la mayor parte del tiempo de la auditoría en el descubrimiento y no en el análisis.

Por eso se recomienda ofrecer a los auditores la documentación de la API y realizar la auditoría con un enfoque más bien gris. Para ello se piden unos requerimientos y así poder realizar la auditoría:

  • Documentación.
  • En caso de tener Swagger, el fichero que define las operaciones (yaml o json).
  • Credenciales/Token.
  • Alcance.

Antes del día en que inicia la auditoría se deben hacer algunas comprobaciones para evitar encontrarse problemas que impidan poder empezar y estar parados:

  • Comprobar la conexión y realizar alguna petición.
  • Comprobar las Credenciales/Token.
  • Ver por encima la documentación.

De esta manera nos aseguramos de que todo está funcionando y tenemos lo que necesitamos para realizar la auditoría.

Si, por el contrario, el proyecto API no dispone de documentación nos toca descubrir los endpoints o rutas válidas con diccionarios especializados. El hacer un reconocimiento de la organización nos puede ayudar a montar un diccionario adecuado. Y claro, para ello nos ayudaríamos con técnicas como Fuzzing.

Fuzzing

Fuzz o Fuzzing es una técnica de testing de software orientada a caja negra. Básicamente consiste en encontrar bugs, errores o malas implementaciones mediante el envío de datos inválidos, inesperados o incluso arbitrarios de forma automática.

El Fuzzing es muy importante durante el API testing ya que se utilizará para encontrar las rutas, los métodos e incluso parámetros o valores de cada endpoint si se ha enfocado en modo caja negra. Para la realización de fuzzing necesitaremos conocer las herramientas y los diccionarios que utilizaremos.

Existen diversas herramientas en el mercado, unas más eficientes que otras. Entre ellas se encuentra Wfuzz, una herramienta diseñada para bruteforcing en aplicaciones web, la cual es muy versátil ya que permite fuzzear cualquier parámetro, valor, método, cabecera, directorio, fichero o incluso extensión que pueda contener una petición HTTP.  

Los diccionarios son un conjunto de palabras comunes para un determinado objetivo, como pueden ser rutas, valores, nombres de usuario o incluso contraseñas, agrupadas en un solo fichero de texto plano. Existen diccionarios de tamaños muy distintos, que van de decenas a millones de palabras. Es muy importante detectar la tecnología utilizada en el servidor para poder utilizar un diccionario más específico acorde a esa tecnología, por ejemplo, un Microsoft IIS Server no distingue entre mayúsculas y minúsculas (UserLogin = userlogin) en los endpoint (rutas), por lo que podremos utilizar un diccionario más pequeño (todo minúscula) y conseguir una mayor eficiencia en el fuzzeo enviando un menor número de peticiones al servidor.

SecLists es una colección de múltiples tipos de listas utilizadas durante una evaluación de seguridad reunidas en un único repositorio de GitHub.

Enlace: https://github.com/danielmiessler/SecLists

Se debe tener en cuenta también que esta técnica puede llevar a errores o sobrecarga del servidor que provoquen una denegación de servicio, por lo que es importante tener cuidado y aplicar limitaciones a nivel de peticiones por segundo, limitar threads, etc.

Referencias:


Autores: Roger Martín y Mario Valiente
Dpto. Auditoría