Falsificación de peticiones del lado del servidor
Las vulnerabilidades de Falsificación de Peticiones del Lado del Servidor ocurren cuando un usuario es capaz de hacer que una aplicación haga peticiones HTTP a un dominio determinado por el atacante. Si una aplicación tiene acceso a redes privadas/internas, un atacante también podría hacer que la aplicación realizara peticiones a servidores internos.
Vamos a verlo más de cerca con algunos ejemplos para entender mejor cómo se ve en acción.
Considere una API que toma una URL de un usuario y genera una imagen de la URL proporcionada por el usuario, como para una vista previa o exportación de una página.
ts
let url = request.params.url;
let response = http.get(url);
let render = response.render();
return render.export();
Debido a que el parámetro URL es controlado por el usuario, permite a un atacante simplemente acceder a cualquier URL que desee. En algunos casos, dependiendo de la biblioteca utilizada para acceder a la URL, incluso puede tratarse de archivos locales utilizando el esquema 'file://'.
Una forma común de abusar de una vulnerabilidad SSRF, cuando está alojada en AWS, es utilizarla para acceder a la API de metadatos de AWS, que puede contener credenciales para la API de AWS. Esto puede conducir a un mayor acceso a otros recursos de AWS dentro de la cuenta que, como se puede imaginar, no es lo ideal.
Mitigación
Mitigar las vulnerabilidades SSRF puede ser muy complicado a veces, y depende en gran medida de lo que el código en cuestión está tratando de lograr. Dependiendo de los requisitos, hay diferentes mitigaciones que se pueden poner en marcha.
Evite las URL determinadas por el usuario
En algunos casos, es posible implementar una función de forma que no dependa de que el usuario proporcione una URL arbitraria. Si esto es posible, es la forma más eficaz de mitigar el riesgo de SSRF.
Minimizar capacidades
Si estás implementando una función de exportación a PDF, uno podría inclinarse a simplemente usar un navegador sin cabeza y tomar una captura de pantalla de la página. Esto no siempre es aconsejable, dada la complejidad de los navegadores y el gran número de capacidades y superficies de ataque que los navegadores exponen.
Es importante utilizar la herramienta adecuada para cada tarea. En algunos casos, un simple cliente HTTP será suficiente. Siempre hay cosas que se pueden hacer para minimizar las capacidades y, por tanto, la superficie/vectores de ataque disponibles. Por ejemplo, en el caso de un cliente HTTP:
- Desactivar el seguimiento de redirecciones
- Desactivar todos los esquemas que no sean HTTPS
Existen algunos escollos
Redirecciones e iframes
Una forma habitual de protegerse contra SSRF en recursos privados (direcciones IP o nombres de host internos) es analizar la URL proporcionada por un usuario y utilizar una "lista de denegación" para impedir el acceso a recursos sensibles.
Vale la pena señalar que este método no es efectivo en la mayoría de los casos, ya que puede ser evitado 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 sensible, ya sea a través de un HTTP 301/302, una redirección HTML Meta, estableciendo la URL actual con Javascript en la carga, o incrustando un iframe que muestre un recurso interno. De este modo se evita cualquier intento de validar la URL original.
DNS Rebinding
Otro "tipo" de redirección 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
- Tome el nombre de host, y hacer una búsqueda DNS
- Rechazar la URL si resuelve a una IP interna/privada, o aceptar la URL si es una IP pública.
Este método no es realmente efectivo debido a que es vulnerable al "DNS Rebinding". DNS Rebinding funciona debido al comportamiento estándar de la mayoría de las pilas de red (como las de Linux y Windows) cuando una conexión TCP es cerrada por un host remoto.
Cuando un host remoto cierra forzosamente una conexión, intentará reconectarse después de hacer otra consulta DNS para re-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 con un puerto HTTP abierto con un TTL (Time-to-live) muy corto.
- Envía la URL (ejemplo: https://rebinding.attacker.com/) a la aplicación vulnerable. Comprueba que la IP resuelta no es privada, que no lo es, y luego procede con la operación solicitada bajo la creencia de que es seguro
- Una vez realizada la conexión HTTP, la entrada DNS para "rebinding.atacante.com" se cambia por una dirección IP interna
- La conexión HTTP se cierra forzosamente
- Esto hace que la aplicación vuelva a resolver la dirección IP de "rebinding.attacker.com", que ahora apunta a una dirección IP interna.
- Dado que la protección de la resolución de IP ya se ha producido, y que la nueva resolución de la entrada DNS y la nueva conexión se producen en el núcleo, la aplicación no es consciente del hecho de que la IP ha cambiado.
De este modo, se evita la protección contra el suministro de URL que resuelvan 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 corresponda con una dirección IPv4 a la que se desee acceder.