Falsificación de solicitud del lado del servidor
Las vulnerabilidades de falsificación de petición en el lado del servidor (SSRF) ocurren cuando un usuario logra que una aplicación realice peticiones HTTP a un dominio determinado por un atacante. Si la aplicación tiene acceso a redes privadas o internas, el atacante también podría hacer que la aplicación realice peticiones a servidores internos.
Analizaremos esto más a fondo con algunos ejemplos para entender mejor cómo se manifiesta en la práctica.
Imagina una API que toma una URL proporcionada por el usuario y genera una imagen de dicha página, por ejemplo, para una vista previa o una exportación.
ts
let url = request.params.url;
let response = http.get(url);
let render = response.render();
return render.export();
Dado que el parámetro de la URL está controlado por el usuario, esto permite que un atacante acceda a cualquier URL que desee. En algunos casos, dependiendo de la biblioteca utilizada para acceder a la URL, incluso se puede acceder a archivos locales mediante el esquema «file://».
Una forma común de explotar una vulnerabilidad SSRF, cuando se aloja en AWS, es utilizarla para acceder a la API de metadatos de AWS, la cual puede contener credenciales para la API de AWS. Esto puede derivar en un acceso mayor a otros recursos de AWS dentro de la cuenta, lo cual, como puedes imaginar, no es nada recomendable.
Mitigación
Mitigar las vulnerabilidades SSRF puede ser complicado en ocasiones y depende en gran medida de lo que el código en cuestión intente lograr. Según los requisitos, existen diferentes medidas de mitigación que se pueden implementar.
Evitar URLs determinadas por el usuario
En algunos casos, es posible implementar una funcionalidad sin depender de que el usuario proporcione una URL arbitraria. Si esto es posible, es la forma más efectiva de mitigar el riesgo de SSRF.
Minimizar capacidades
Si estás implementando una función de exportación a PDF, podrías sentir la tentación de usar simplemente un navegador sin interfaz gráfica (headless) para tomar una captura de pantalla de la página. Esto no siempre es aconsejable, dada la complejidad de los navegadores y la gran cantidad de capacidades y superficies de ataque que exponen.
Es importante utilizar la herramienta adecuada para cada tarea. En algunos casos, un cliente HTTP sencillo será suficiente. Siempre hay medidas que se pueden tomar para minimizar las capacidades y, por tanto, la superficie o los vectores de ataque disponibles. Por ejemplo, en el caso de un cliente HTTP:
- Deshabilitar el seguimiento de redirecciones
- Deshabilitar todos los esquemas excepto HTTPS
Existen algunos riesgos
Redirecciones e iframes
Una forma común de protegerse contra SSRF en recursos privados (direcciones IP o nombres de host internos) es analizar la URL proporcionada por el usuario y utilizar una «lista de denegación» para impedir el acceso a recursos confidenciales.
Cabe señalar que este método no es efectivo en la mayoría de los casos, ya que puede ser evadido en escenarios donde el cliente sigue redirecciones HTTP, redirecciones HTML/JavaScript o puede renderizar elementos complejos como iframes.
Un atacante puede proporcionar una URL a una aplicación vulnerable que aloje una página que redirija a un recurso confidencial, ya sea mediante un redireccionamiento HTTP 301/302, una etiqueta meta de redirección HTML, estableciendo la URL actual con Javascript al cargar, o incrustando un iframe que muestre un recurso interno. Esto elude eficazmente cualquier intento de validar la URL original.
Revinculación de DNS
Otro "tipo" de redireccionamiento también puede realizarse a través de DNS. Una forma común de intentar prevenir ataques SSRF es hacer lo siguiente:
- Analizar la URL proporcionada
- Tomar el nombre de host y realizar una búsqueda DNS
- Rechazar la URL si se resuelve en una IP interna/privada, o aceptarla si es una IP pública
Este método no es realmente efectivo, ya que es vulnerable a la "revinculación de DNS". La revinculación de DNS funciona debido al comportamiento estándar de la mayoría de las pilas de red (como las de Linux y Windows) cuando un host remoto cierra una conexión TCP.
Cuando un host remoto cierra una conexión de forma forzada, el sistema intentará reconectarse tras realizar otra consulta DNS para volver a resolver la dirección IP.
Esto permite a un atacante hacer lo siguiente:
- Crear una entrada DNS para `rebinding.attacker.com` con una dirección IP pública que tenga un puerto HTTP abierto y un TTL (tiempo de vida) muy corto
- Enviar la URL (ejemplo: https://rebinding.attacker.com/) a la aplicación vulnerable. Esta verifica que la IP resuelta no sea privada, lo cual es correcto, y luego procede con la operación solicitada bajo la creencia de que es segura
- Una vez establecida la conexión HTTP, la entrada DNS de “rebinding.attacker.com” se cambia a una dirección IP interna
- La conexión HTTP se cierra de forma forzada
- Esto provoca que la aplicación vuelva a resolver la dirección IP de “rebinding.attacker.com”, que ahora apunta a una dirección IP interna
- Debido a que la protección de resolución de IP ya se ha producido, y la nueva resolución de la entrada DNS y la reconexión ocurren en el kernel, la aplicación no es consciente de que la IP ha cambiado
Esto elude eficazmente la protección contra el suministro de URLs que se resuelven en direcciones IP privadas.
IPv4 frente a IPv6
Otra forma común de eludir cualquier "lista de denegación" es el uso de IPv6. Dado que todas las direcciones IPv4 pueden expresarse en términos de una dirección IPv6, a menudo es posible eludir las listas de denegación utilizando una dirección IPv6 que también se asigne a una dirección IPv4 a la que se desee acceder.
Programación segura y práctica
Explore las directrices de programación segura para comprender y mitigar vulnerabilidades de software como el OWASP Top 10, y sumérjase en misiones de formación guiada para practicar en simulaciones de aplicaciones del mundo real.