Mejores Prácticas: Seguridad REST API.

Mejores Prácticas: Seguridad REST API.

Introducción

Gran parte de los sitios web que visitamos a diario están construidos y consumen una API, la cual está siendo expuesta a través de internet y cualquier persona puede encontrar esa URL pero, entonces, ¿Cómo nos aseguramos de tener una API segura?.

Eso es algo que responderé el día de hoy, intentando dar algunos tips y buenas prácticas para esto.

Protocolos Seguros


Es bien conocido por todos que cuando un sitio es seguro, es porque en nuestro navegador aparece un candado de color verde, más el protocolo HTTPS antes de la URL del sitio que estamos visitando, bueno, esto también aplica para las API.

Ya sea que estamos construyendo una API o consumiendo una, debemos estar seguros de utilizar TLS (Transport Layer Security) la cual protege la información de tu API y la del usuario cifrando los mensajes mientras están en transito de un punto a otro. Es decir, mantiene una comunicación segura entre el cliente (Tú y tu navegador) y el servidor (Tu API).

TLS requiere ser emitida por una autoridad certificada, para que se pueda tener esa seguridad de la información, muchos de los proveedores de servicios como AWS, GCP o Azure, manejan estos certificados por ti, por lo cual no tienes mucho por preocuparte, pero si no utilizas alguno de estos, entonces lo tienes que manejar por tu propia cuenta, afortunadamente existe Let’s Encrypt que es la manera más sencilla de obtener un certificado seguro y legitimo para tus servicios web como una API.

Genera API Keys.


Mientras que los endpoints de tu API proveen y exponen información que puede ser delicada hasta cierto punto, es necesario tener como mecanismo de defensa, una llave/s para que puedan acceder y consumir los endpoints de tu API.

Pero, ¿Para qué es necesaria una API Key?, y te responderé con lo siguiente:

Imagina que tienes una API en la cual subes y compartes tus maravillosas recetas de cocina con las personas, personas las cuales consumen esa información a través de tu Aplicación Móvil, la cual consume esa API. Tú deseas que esa información sea únicamente accedida por tu Aplicación Móvil, pero sin una Key que restrinja el acceso a tu API, cualquier persona que tenga la URL podrá hacer peticiones a tu API.

Este es un mecanismo de seguridad el cual va a requerir a las aplicaciones que consuman tu API, mandar de manera obligatoria una llave (Key), la cual puede variar dependiendo del usuario y/o servicio que lo consuma y que incluso pueda caducar cada cierto tiempo.

Existen distintas maneras de pedir y enviar dicha llave, pero acá mostraré las dos más usadas y que a mi parecer, son las mejores.

Enviar la llave en la parametros de la URL.

Muchos servicios deciden pedir las llaves en los query params de la URL, ejemplo:

<https://api-la-mejor-receta.codingtaco.com/recipes?api_key=564d5346w1e331645415e>

Y es una opción válida.

Enviar las llaves en los headers de la petición

Otros tantos, deciden mandar las keys en los heades, como lo siguiente:

$ curl -H "Authorization: MY_API_KEY" <https://api-la-mejor-receta.codingtaco.com/recipes>

En esta otra manera, lo que hacemos es mandar la llave a través de los headers y listo.

De esta manera nos aseguramos que sólo los usuarios y/o servicios autorizados, puedan tener acceso a tus deliciosas recetas.

Hosts Permitidos


Existe otra buena práctica y debería ser completamente obligatoria el tener Allowed Hosts (Hosts Permitidos), esto para garantizar una correcta seguridad de la API, y permitir que únicamente dominios y/o aplicaciones «conocidas» puedan hacer peticiones y de lo contrario levantar un código de error HTTP, que bien podría ser un HTTP 401 Unauthorized, tenemos la siguiente situación.

Imagina que construiste o tienes un frontend, el cual va a consumir tu API y tiene como nombre de dominio la-mejor-receta.com, y es desde esa dirección la cual el frontend hará las peticiones hacía tu servicio, si tú no defines que únicamente quieres que desde ese host se comunique a tu API, entonces cualquier persona que encuentra la dirección de tu API podrá hacerle peticiones y sobrecargar tu servicio.

Esto puede aumentar el consumo de CPU, de memoria y no estar disponible para cuando usuarios que realmente necesiten consumir información, no puedan tener acceso.

En Python por ejemplo y más específicamente en Django, es tan fácil como agregar los hosts que necesitamos en nuestro archivo de settings:

ALLOWED_HOSTS = ["la-mejor-receta.com", "*.codingtaco.com"]

En otros lenguajes y/o frameworks es similar o agregar un middleware para que revise el hosts antes de la petición.

Limitar Peticiones


Esta es una buena práctica muy importante, en especial para API’s que se ofrecen sobre demanda y necesitan limitar la cantidad de peticiones que un usuarios/servicio te puede realizar y para eso existe Throttling, lo cual no es más que un termino utilizado para limitar el número de peticiones que un usuario puede realizar.

Así también, puede ser una práctica de seguridad muy buena para evitar en otros casos, como usuarios maliciosos, que intenten atacar tu API, etc.

Para este no hay un ejemplo conciso, ya que algunas veces se puede configurar desde tu propia API o desde el servidor como es NGINX o Apache.

Conclusiones


Para concluir, cabe menciones que estas no son reglas escritas en piedra, la cantidad de recursos acerca del tema es muy basto, yo he puesto las que más me han servido y apoyado a poder tener una API segura, estable y con un bajo consumo de recursos.

Espero que sea de mucha ayuda y recuerda siempre pensar en seguridad antes de lanzar tus productos y servicios a producción, así te evitarás muchos problemas.