Las APIs son cada vez más vulnerables a los ataques de seguridad. Pero lo cierto es la que mayoría de amenazas se pueden prevenir y evitar. Te contamos en este post cómo hacerlo dependiendo de cuál sea el tipo de ataque.

Recuerda que en un post anterior identificamos las diferentes vulnerabilidades a nivel de API y los principios básicos que se deben tener presentes a la hora de su implementación.

Validación de los parámetros

Para el caso de vulnerabilidades referente a los parámetros se recomienda establecer las siguientes medidas:

El primer paso para cualquier implementación de API es comprobar la validez de todos los datos entrantes verificando su formato, su validez y garantizar que no puede causar daño al sistema.

La defensa más efectiva para los ataques de inyección consiste en validar los datos entrantes contra un esquema estricto utilizando formatos específicos de datos incluso rangos y/o conjuntos de posibles valores, sin olvidarnos de limitar el tamaño en caso de campos de texto libres.

Hay que tener en cuenta que la mayoría de los esquemas generados de manera automática con las herramientas de desarrollo producen esquemas demasiado amplios, lo que implica dedicar especial atención a los posibles errores de validación.

Una posible lista de consejos para realizar esta validación sería la siguiente:

Cuando se crean/actualizan datos en el servidor se envía información desde el cliente de la API en cuyo caso el servidor nunca debe asumir el tipo de contenido por defecto.

Siempre debe solicitar la cabecera Content-Type por parte del cliente y validar primero que admite ese tipo de contenido, por ejemplo application/json y segundo que el cuerpo de la petición contiene la información en dicho formato.

En caso de que el cliente no envie la cabecera el servidor debe contestar con un código HTTP 406 No Aceptable, y en caso de que indique uno que no sea válido por parte del servidor, devolver un 415 Unsupported Media Type.

Es habitual que los servicios Rest admitan múltiples tipos de respuesta, por ejemplo: application/json y application/xml y el cliente especifique el orden del formato en el que prefiere recibir los datos haciendo uso de la negociación de contenido con la cabecera Accept.

No se debe admitir esta cabecera vacía o sin un valor específico, debe ser obligatorio en las peticiones desde el cliente indicar el formato que prefiere en la respuesta.

En caso de que el cliente no envie la cabecera Accept el servidor debe contestar con un código HTTP 406 No Aceptable y en caso de que indique uno que no sea válido un 415 Unsupported Media Type.

Debido a que hay muchos tipos MIME para los tipos de respuesta típicos, es importante documentar específicamente para los clientes los tipos MIME que se deben usar en cada API.

Los atacantes pueden manipular cualquier parte de la solicitud HTTP incluida la URL para intentar evitar los mecanismos de seguridad del sitio.

Ataques típicos a nivel de URL incluyen: navegación forzada, inserción de comandos, desbordamientos del búfer, manipulación de campos ocultos, ataques de cadenas de formato, etc.

Detalle de la vulnerabilidad: https://vulncat.fortify.com/en/detail?id=desc.dynamic.xtended_preview.often_misused_http_method_override

Los servicios basados ​​en XML deben garantizar que están protegidos contra ataques comunes basados ​​en XML mediante el uso de análisis XML seguro. Normalmente, esto significa proteger contra ataques de entidad externa XML, ajuste de firma XML, etc.

También es recomendable utilizar siempre serialializadores para evitar ataques de inyección XML. garantizando que el contenido proporcionado por el cliente sea una XML válido.

Una de las principales preocupaciones de las codificaciones JSON es evitar la ejecución arbitraria de código remoto Javascript en el navegador o en el servidor.

Para evitarlo resulta vital usar un serializador JSON para codificar correctamente los datos enviados por el cliente y evitar la ejecución de código incluido dentro de la información introducida por el cliente.

Como se ha explicado antes, toda la información que va en la url es susceptible de ser almacenada y hay que evitar como sea incorporar información sensible en la misma: como números de cuenta, datos de la tarjeta, teléfono, email o incluso datos de salud personal así como datos asociados a la autenticación y autorización DOM tokens o password.

El envío de claves como parte de la URL puede hacer que la clave se vea comprometida.

Como se explica en IETF RFC 6819, dado que los detalles de URI pueden aparecer en los registros del sistema o del navegador, otro usuario podría ver los URI desde el historial del navegador, lo que hace que las claves de API, las contraseñas y las fechas confidenciales en los URI de API sean fácilmente accesibles.

Para evitarlo algunas recomendaciones son:

En el momento en el que se produce un error al invocar una API se aconseja devolver por parte del servidor un error que sea suficientemente explicativo para que el cliente pero no enviar el stack trace del error del backend.

Si se propaga el error devuelto por el backend, incluyendo el stack trace, potencialmente puede convertirse en una fuga de información para el usuario malintencionado revelando la implementación de la arquitectura subyacente con nombres de clases, paquetes, versiones, servidores e incluso consultas SQL.

Los atacantes pueden explotar esta información enviando peticiones a la API con malas intenciones. Para evitarlo se recomienda devolver un objeto de error con información de manera equilibrada, es decir, que incluya suficiente información como para que el cliente identifique el error pero sin desvelar detalles técnicos del error producido.

Lo que se recomienda es enviar el código HTTP asociado con un alias y mensaje de error que sea suficientemente explicativo y sin incorporar el stack trace del backend.

Los API gateway se pueden utilizar para transformar los mensajes de error de los backend en mensajes estandarizados para que todos los errores sean similares y eliminar la exposición de la información y de la estructura de error del backend.

Autenticación y autorización

Para el caso de vulnerabilidades asociadas a los flujos de autorización y autenticación se recomienda:

No todos los métodos HTTP realizan la misma funcionalidad ni todas los clientes de la API deben tener permiso y acceso a dichos métodos.

Es habitual que sobre un mismo recurso se exponen métodos de consulta como el GET y métodos con un rol operativo como POST, PUT, y DELETE siendo estas últimas operaciones susceptibles de un control de acceso más estricto, ya que solo personas con permisos especiales como un gestor o los propios dueños de los datos las puedan realizar.

Para asegurar que las personas correctas acceden a los métodos a los que están autorizados debe implementarse algún método de autorización como Oauth o OpenId Connect, así como hacer uso de los scopes para implementar esa granularidad de acciones sobre un recurso.

En resumen, es importante que el servicio restrinja correctamente los verbos permitidos, de modo que solo funcionen los métodos autorizados para las personas adecuadas y, en caso contrario, devolver un código HTTP 403 Forbidden.

Transporte

Para el caso de vulnerabilidades asociadas a ataques a nivel de transporte:

Es importante asegurar sobre todo sobre los verbos PUT, PATCH, POST y DELETE estén protegidos contra ataques CSRF normalmente haciendo uso de un enfoque basado en token como el estándar OAuth.

Aún así es posible generar tokens aleatorios si hay errores XSS dentro de la aplicación, luego también hay que asegurarse por parte del servicio su prevención de ataques XSS.

https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet

También se debe considerar el uso de certificados del lado del cliente con autenticación mutua para proporcionar protección adicional sobre todo para servicios cuya operativa implique un mayor control y/o privilegios del cliente.

El inconveniente del aumento de latencia por el uso de TLS es ínfimo en sistemas actuales frente a la seguridad que aporta al usuario final y a la información expuesta.

Este objeto JSON incluye el valor del hash de la firma digital del cuerpo del mensaje que se envía lo cual permite garantizar la integridad del mensaje durante su transmisión.

Además JWT no solo sirve para garantizar la integridad del mensaje, sino también la autenticación del remitente/receptor del mensaje. Aquí tienes más información al respecto.

Una buena práctica es imponer una cuota de uso por aplicación para evitar que el backend se vea afectado por un tráfico elevado. Estas limitaciones y control de cuotas suelen implementarse mediante plataformas de gestión de APIs.

Otra de las ventajas de hacer uso de este control de tráfico y el uso de cuotas es minimizar el impacto de ataques por repetición.

Las APIs que se encuentran expuestas al público se enfrentan al desafío de confiar en las peticiones entrantes, incluso en caso de peticiones en las que se niega el acceso por confianza hay APIs que permiten "cortésmente" que el usuario lo intente de nuevo, lo cual puede inducir a reproducir solicitudes de fuerza bruta y de denegación de servicio.

Las medidas en este caso residen en limitar la velocidad entre peticiones o incluso el uso de herramientas de análisis del tráfico para identificar patrones de peticiones de un bot por ejemplo.

También suele ayudar el uso de HMAC con marcas de tiempo para limitar la validez de la transacción un periodo de corto de tiempo, realizar autenticación de dos factores y habilitar tokens de acceso de corta duración con OAuth.

Checklist

Con el objetivo de ayudarnos a que las recomendaciones anteriores se sigan dentro de un proyecto se ha elaborado la siguiente checklist con las medidas de seguridad asociadas a cada categoría de vulnerabilidad y al tipo de riesgo según OWASP para ayudar a mitigarlo.

Conclusiones

Todas las organizaciones con una estrategia de apificación deben abordar la seguridad como un desafío arquitectónico mucho antes que tenga lugar al desarrollo y como muy tarde a la vez que se realiza la implementación para evitar problemas posteriores.

Un error de seguridad de la API puede tener consecuencias significativas, pero con la previsión y la administración adecuadas la mayoría de problemas se seguridad se minimizan notablemente.

En este post hemos visto cómo la mayoría de amenazas potenciales se pueden evitar:

Resulta fundamental promover la capacitación a nivel de seguridad de los desarrolladores desde la propia organización como base en el desarrollo software.

Dentro de este programa formativo o de capacitación, debe enfatizarse también la securización de las APIs para trasladar las implicaciones que tiene la exposición de información a través de ellas y que desde el principio se planteen sus posibles consecuencias para mitigar los problemas antes de que se conviertan en una realidad.

Referencias

Cuéntanos qué te parece.

Los comentarios serán moderados. Serán visibles si aportan un argumento constructivo. Si no estás de acuerdo con algún punto, por favor, muestra tus opiniones de manera educada.

Suscríbete

Estamos comprometidos.

Tecnología, personas e impacto positivo.