Cómo prevenir la falsificación de solicitudes del lado del servidor en aplicaciones Node.js
David Ekete
20 de febrero de 2024
0 minutos de lectura
La falsificación de solicitudes del lado del servidor (SSRF) es una vulnerabilidad común que puede aparecer inadvertidamente en cualquier aplicación Node.js. Representa una amenaza importante porque los atacantes pueden manipular un servidor para que realice solicitudes no deseadas a recursos internos y externos.
En este artículo exploraremos SSRF, sus posibles riesgos y las estrategias para mitigarla en aplicaciones Node.js.
Muy recomendado: Toma la lección interactiva sobre falsificación de solicitudes del lado del servidor en Snyk Learn.
¿Qué es SSRF?
La SSRF ocurre cuando un atacante aprovecha las solicitudes que envía el servidor de una aplicación web mediante la manipulación de entradas o de URL.
La manipulación de entradas consiste en modificar datos sin autorización, a menudo generados por usuarios, para aprovechar vulnerabilidades de una aplicación. En cambio, las vulnerabilidades por confusión de URL consisten en alterar URL para engañar a un sistema y hacer que realice acciones no deseadas, como acceder a recursos sin autorización o enviar solicitudes maliciosas.
Bajo la influencia del atacante, el servidor envía solicitudes a las URL manipuladas, que parecen haberse iniciado desde el propio servidor y, por lo tanto, evaden las medidas de seguridad habituales. Un ataque SSRF exitoso puede darle al atacante acceso a recursos internos, bases de datos y archivos, y exponer datos confidenciales, como credenciales.
Por ejemplo, en uno de los incidentes de SSRF más conocidos, un exingeniero de desarrollo de software de Amazon aprovechó una vulnerabilidad SSRF que expuso 140,000 números de Seguro Social, 80,000 números de cuentas bancarias y 1 millón de números de seguro social. La filtración afectó a 106 millones de personas y ocasionó daños por 250 millones de dólares estadounidenses.
Un ejemplo sencillo de ataque SSRF
Para comprender mejor las vulnerabilidades SSRF, veamos un ejemplo concreto. En este escenario, trabajas en una aplicación web que permite a los usuarios ingresar una URL, obtener una imagen desde esa URL y mostrarla.
Si quieres seguir los pasos, clona este repositorio de GitHub, que contiene el código fuente de la aplicación web. Esta aplicación usa Express, un framework de Node.js que simplifica la creación de servicios web. También usa Axios, una biblioteca HTTP que permite realizar solicitudes desde Node.js.
Para clonar el repositorio con Git, ejecuta el siguiente comando:
Nota: Debes tener Git instalado en tu sistema para ejecutar este comando.
Después de clonar el repositorio de GitHub, ejecuta el siguiente comando para instalar las dependencias:
Nota: Debes tener Node.js y npm instalados para ejecutar este comando.
La aplicación tiene tres rutas:
/upload-image-urlpermite que un usuario cargue una imagen mediante una URL. Es de acceso público y, a primera vista, no parece causar ningún daño./usersdevuelve toda la información de los usuarios de tu aplicación. No debería ser de acceso público./users/:id/profiledevuelve el perfil de un usuario específico. No debería ser de acceso público.
Inicia la aplicación con el siguiente comando:
Cuando envíes una solicitud con Insomnia (o cualquier otra herramienta para probar API) a /upload-image-url con una URL válida de imagen, deberías obtener la siguiente respuesta:

Cuando usuarios maliciosos reciben esta respuesta, saben que tu servidor realiza llamadas a API internamente usando la URL proporcionada. Ahora pueden probar distintas URL para averiguar la estructura interna de tu servidor o enviar URL, como http://169.254.169.254 o http://instance-data, para acceder a los metadatos de Amazon Web Services (AWS) de tu aplicación si esta se ejecuta en una instancia de Amazon Elastic Compute Cloud (Amazon EC2). Este tipo de SSRF se conoce como SSRF básica.
La SSRF básica ocurre cuando un atacante manipula el servidor para que envíe solicitudes a recursos no deseados, a menudo sin conocer directamente la estructura interna del servidor. En este caso, el atacante generalmente puede ver la respuesta a la solicitud.
Otro tipo de SSRF es la SSRF ciega, en la que un atacante envía solicitudes SSRF, pero no tiene acceso directo a la respuesta del servidor. En su lugar, se basa en el comportamiento de la aplicación para confirmar indirectamente que el ataque SSRF tuvo éxito.
Por ejemplo, si un atacante decide probar la URL localhost:8050/users, recibirá la siguiente respuesta (es decir, una SSRF básica), que expone los datos de todos tus usuarios:

Tu código es vulnerable a ataques SSRF porque acepta URL proporcionadas por los usuarios sin validarlas ni controlar el acceso adecuadamente. Esto permite que los usuarios envíen solicitudes a recursos internos o privados potencialmente confidenciales. Tampoco hay ningún mecanismo para permitir o bloquear dominios específicos mediante listas de permitidos o de bloqueados.
Para mitigar esta vulnerabilidad, tu código debe depurar las entradas de usuario, restringir el acceso a dominios de confianza, usar firewalls y establecer prácticas adecuadas de manejo de errores y monitoreo.
Cómo prevenir vulnerabilidades SSRF en Node.js
Si quieres prevenir vulnerabilidades SSRF en tu aplicación Node.js, tienes varias opciones. En la siguiente sección conocerás algunos métodos y prácticas recomendadas que pueden ayudarte.
Usa las versiones más recientes de las bibliotecas
Usar las versiones más recientes de las bibliotecas es importante para mejorar la seguridad de tu aplicación. Las nuevas versiones suelen incluir parches de seguridad esenciales y correcciones de errores, que pueden reducir la vulnerabilidad de tu aplicación ante ataques comunes, como SSRF.
Sin embargo, al actualizar, es fundamental tener en cuenta los problemas de compatibilidad, los cambios incompatibles y la compatibilidad con versiones anteriores. Presta atención a los ciclos de obsolescencia, actualiza gradualmente las bases de código grandes y analiza periódicamente las dependencias para detectar posibles vulnerabilidades de seguridad y mantener una aplicación segura y bien mantenida.
Usa Snyk para actualizar las bibliotecas y mantener tus dependencias al día y libres de vulnerabilidades de seguridad conocidas públicamente.
Usa un firewall
Un firewall es un sistema de seguridad de red que actúa como barrera de protección y monitorea y controla el tráfico de red según reglas predefinidas.
Para prevenir ataques SSRF con firewalls, puedes implementar un firewall de aplicaciones web (WAF) que inspeccione y bloquee solicitudes maliciosas. Para ello, crea una lista de permitidos con dominios de confianza y bloquea las URL o direcciones IP sospechosas.
Depura las entradas de usuario
La depuración de entradas es una práctica de seguridad que permite limpiar y modificar los datos proporcionados por los usuarios para que puedan procesarse de forma segura en tu aplicación. Su propósito principal es prevenir vulnerabilidades de seguridad que pueden surgir de entradas no confiables o maliciosas.
Puedes prevenir la SSRF depurando todas las entradas de usuario para asegurarte de que las URL tengan el formato correcto y no contengan caracteres inesperados antes de procesarlas en tu aplicación.
Aunque la depuración de entradas puede ayudar a garantizar que las URL tengan el formato correcto, no debes usarla de forma aislada.
Exige esquemas de URL
Otra forma de prevenir vulnerabilidades SSRF es exigir esquemas de URL específicos. Al definir los esquemas de URL permitidos en tu aplicación (p. ej., HTTP y HTTPS), puedes impedir que los usuarios ingresen URL con esquemas potencialmente peligrosos o no deseados (p. ej., file:// y ftp://).
Para implementar esto en la aplicación que clonaste antes, puedes verificar explícitamente que la URL proporcionada comience con un esquema permitido, normalmente http:// o https://. Si la URL no cumple con estos esquemas, puedes rechazarla:
Crea una lista de permitidos con dominios de confianza
Crear una lista de permitidos con dominios de confianza previene las vulnerabilidades SSRF al permitir solicitudes únicamente a dominios específicos que se sabe que son seguros y necesarios para tu aplicación.
Para implementarlo en la aplicación que clonaste antes, crea un arreglo (en una aplicación real, quizá necesites un método más sólido) con los dominios en los que confías y a los que permites que tu aplicación envíe solicitudes. Deben ser dominios con los que tu aplicación interactúe y que considere seguros.
Luego, antes de solicitar la URL proporcionada por el usuario, verifica si coincide con alguno de los dominios de confianza de tu lista. Si no coincide, bloquea la solicitud. Después de implementarlo, tu ruta /upload-image-url debería verse así:
Este código modifica la ruta /upload-image-url al agregar un arreglo de dominios permitidos, verificar si la URL proporcionada por el usuario forma parte de la lista y rechazar la solicitud si la URL no está incluida.
Usa la extensión de Snyk para IDE para detectar vulnerabilidades
Snyk es una herramienta de seguridad popular que puede ayudar a identificar y corregir vulnerabilidades, incluida la SSRF, en bibliotecas de código abierto. Snyk ofrece integraciones con distintos entornos de desarrollo e IDE, incluido Visual Studio Code (VS Code).
Para instalar la extensión de Snyk para IDE en VS Code, abre la vista Extensiones haciendo clic en el ícono cuadrado de la barra lateral izquierda o presionando Ctrl + Shift + X (o Cmd + Shift + X en macOS):

Busca "Snyk" en Marketplace de extensiones y haz clic en el botón Instalar junto a la extensión de Snyk:

Después de instalar la extensión, debes autenticarla con tu cuenta de Snyk. Si no tienes una, asegúrate de crear una ahora. Haz clic en el ícono de Snyk e inicia sesión con tus credenciales de Snyk.
A continuación, abre en VS Code el repositorio del proyecto que clonaste. Deberías ver un mensaje que te pregunta si Snyk debe confiar en estas carpetas: haz clic en Confiar en las carpetas y continuar:

Deberías ver algunas líneas onduladas rojas en partes del código con vulnerabilidades de seguridad (es decir, axios.get en la línea 19). Cuando pases el cursor sobre la línea ondulada, aparecerá una ventana emergente con una explicación de la vulnerabilidad.

También puedes hacer clic en el ícono de Snyk y seleccionar SEGURIDAD DEL CÓDIGO para ver los problemas de seguridad. Al seleccionar una vulnerabilidad, Snyk abre la barra lateral izquierda y proporciona ejemplos de código para ayudarte a resolver el problema.

Conclusión
En este artículo aprendiste que es fundamental proteger tus aplicaciones Node.js contra la SSRF, además de conocer algunas estrategias y prácticas recomendadas que pueden ayudarte a lograrlo.
Al usar las versiones más recientes de las bibliotecas, exigir esquemas de URL, implementar listas de permitidos y usar herramientas de seguridad como Snyk, puedes reducir considerablemente la probabilidad de que haya vulnerabilidades SSRF en tus aplicaciones. Además, al integrar Snyk en tu flujo de desarrollo, puedes detectar de manera eficiente la SSRF y otras vulnerabilidades en tu código antes de que lleguen a producción, reforzando tu código y protegiendo tus sistemas contra posibles ataques.
¡No esperes más! Empieza hoy a proteger tus aplicaciones con Snyk.
Empieza con los desafíos de Capture the Flag
Aprende a resolver desafíos de captura la bandera con nuestro taller virtual introductorio a pedido.


