En Mi Local Funciona

Technical thoughts, stories and ideas

Definición de APIs: SwaggerHub y 42Crunch el tándem perfecto

Publicado por Pedro de la Fuente el

Arquitectura de SolucionesSwaggerDevSecOpsSeguridad APIs42CrunchS-SDLC

En este post abordaremos conceptos de cara a la seguridad de las APIs y cómo evitar los principales riesgos. Para este fin trabajaremos con la definición del API y haremos uso de algunas herramientas que facilitan este proceso de forma continua, y por tanto alineada con la cultura DevSecOps como parte de un S-SDLC (Ciclo de vida de desarrollo seguro de software).

Según OWASP (Open Web Application Security Project) algunas de las mayores vulnerabilidades de aplicaciones web son:

  1. Inyección de código.

  2. Exposición de Datos Sensibles.

  3. Configuración de Seguridad inexistente.

  4. Cross Site Scripting (XSS).

  5. Entidades Externas de XML (XXE)

  6. Registros y Monitorización insuficientes.

Empecemos con un ejemplo de Definición de API REST sencilla con un método de escritura y uno de lectura.

Para la definición hemos usado un editor que nos proporciona SwaggerHub:

apidef1

Como vemos son definiciones válidas. Si utilizamos algún generador de código no tendríamos ningún problema y nos funcionaría, pero... ¿Es nuestra API segura?
La respuesta es NO.

¿Qué vulnerabilidades tenemos?

1 - Ninguno de nuestros métodos tiene un Content-Type definido con lo que no estamos acotando el formato de los datos de entrada y salida. Esto podría suponer que nuestra API seria vulnerable a:

  • Entidades externas de XML (XXE).

  • Desbordamiento de búfer.

  • Errores de decodificación

  • Ataques de inyección código.

2 - No existe definición de seguridad. A menudo se crean este tipo de APIs para ser utilizadas desde las páginas web de empresas y las aplicaciones móviles. Nadie espera que alguien sepa que la API existe, pero los atacantes pueden analizar el código de la aplicación, o escuchar el tráfico de la API y hacer ingeniería inversa.
Una vez que los atacantes han descubierto ésto, pueden comenzar a usar la API porque no requiere ninguna autenticación.

3 - Los datos de entrada de nuestro esquema no tienen ningún tipo de validación. Esto puede hacer que el servidor backend falle de forma inesperada y abra la puerta a nuevos ataques. Por ejemplo, podría lanzar una excepción y devolver un stack trace en el error. La traza podría contener información del software usado en la implementación. Esto permitiría al atacante usar vulnerabilidades conocidas del software para hacer exploit y atacar el servidor.

4 - Por último también es normal encontrarse definiciones de APIs con códigos de respuesta pobres o escasos. Los atacantes se esfuerzan por hacer que las APIs se comporten de una manera inesperada para aprender más sobre su sistema o para causar una violación de datos. Por ello es importante especificar los códigos de respuesta adecuados para minimizar este problema.

¿Cómo corregimos ésto?

1 - Para el primer problema tenemos una fácil solución. Simplemente añadiendo a los métodos un Content-Type concretamos el formato de los datos de entrada y salida, por ejemplo:

2 - En cuanto a la definición de la Seguridad el problema requiere una solución en dos partes:

La primera pasa por definir una configuración de seguridad como en el siguiente ejemplo:

Por otro lado, necesitamos asignarle el scope a cada uno de nuestros métodos, con lo que el resultado sería el siguiente:

3 – Respecto a la validación de parámetros el remedio pasa por acotar la entrada de datos al formato que esperamos. Cada tipo de dato tiene una configuración característica. Veamos algunos ejemplos de cómo debería quedar:

  • Para los parámetros tipo String:
  • Parámetros de tipo numérico:
  • Arrays:

4 – Para tener un mínimo de códigos de respuesta controlados se deberían definir los siguientes:

¿Existen herramientas que nos ayuden?

Como podemos ver son varios los temas a tener en cuenta de cara a la definición de las APIs. Uno de los problemas que nos podemos encontrar en el desarrollo es que las personas encargadas de definir e implementar las APIs no tengan formación o tiempo para atender todo esto.

Para poder filtrar las definiciones de una manera rápida existen herramientas de securización de APIs como 42Crunch. En este caso utilizaremos una de sus funcionalidades para analizar nuestra definición.

Con este fin lo primero que tenemos que hacer es convertir nuestra definición de la API a formato JSON. Dentro de SwaggerHub, donde tenemos nuestra definición, lo podremos hacer fácilmente.

Primero seleccionamos Exportar -> Download API -> JSON-Resolved. Se nos descargará un zip y dentro encontraremos el swagger.json:

Si usamos Visual Studio, existe un plugin de 42Crunch que ya nos permite definir las APIs en YAML también:

Una vez que tengamos nuestro JSON con la definición solo tenemos que subirlo a esta herramienta pública. Hecho esto la herramienta analiza nuestra definición y genera un informe:

Aquí podemos ver la puntuación que recibe nuestra definición, pero no solo nos indica cuales son los posibles problemas, si no también como solucionarlo.

Por un lado, podemos ver si nuestra problemática está en el formato, la seguridad o la validación de los datos. Dependiendo de donde tengamos el aviso, la herramienta nos indica el riesgo en el que incurrimos y las posibles soluciones.

En los siguientes ejemplos, veremos un error de cada tipo y como solucionarlo:

1-Error en la definición del formato OpenAPI

En este caso el error es muy sencillo. El formato OpenAPI numérico no reconoce el uint64 como un tipo válido en la definición. Para repararlo debemos poner un tipo reconocido por OpenAPI, como por ejemplo int64.

2- Error en la definición en la capa de Seguridad

Este problema es mucho más común. Nuestra API de ejemplo tienen un GET en el cual no hemos definido ningún Content-Type con los riesgos que esto entraña y que hemos visto anteriormente. Para solucionar este problema es tan fácil como asignarle un tipo específico, en este caso application/json.

3- Error En la validación de datos

Como vimos anteriormente para definir un tipo numérico, es recomendable indicar un minimum y un maximum, aunque este último no es obligatorio.

Una vez solucionado todos los avisos que nos da 42Crunch veremos que al pasar el API por el auditor nos devuelve una validación de 100% en cuanto a definición.

Conclusiones

Tras revisar las posibles vulnerabilidades que podemos tener en nuestra definición de APIs, hemos visto que existen ciertas herramientas que nos pueden ayudar mucho a solventarlas. https://apisecurity.io/tools/audit de 42Crunch es una de ellas, pero como hemos comentado anteriormente es solo la parte pública. La herramienta completa nos otorga mucha más funcionalidad. Entre otras cosas además de auditar nuestra definición también nos permite escanear nuestros EndPoints desplegados y agregar un firewall especifico para nuestra API. Todo esto lo veremos más a fondo en la siguiente entrega.

¡Síguenos en Twitter para estar al día de las novedades!