Server-Side Request Forgery (SSRF): Capital One y Más Allá
Un SSRF convierte al servidor en un proxy involuntario del atacante. La brecha de Capital One en 2019 demostró que, combinado con servicios de metadatos cloud, un solo SSRF puede exponer 106 millones de registros. Análisis técnico del ataque, variantes, y cómo prevenirlo.
El servidor como proxy involuntario
El 29 de julio de 2019, el FBI arrestó a Paige Thompson en Seattle. Ex ingeniera de Amazon Web Services, Thompson había explotado una vulnerabilidad aparentemente menor en la infraestructura cloud de Capital One para acceder a los datos de 106 millones de clientes: nombres, direcciones, números de teléfono, fechas de nacimiento, ingresos declarados, 140.000 números de seguridad social y 80.000 números de cuenta bancaria.
La vulnerabilidad no era un zero-day sofisticado ni un exploit de memoria. Era un Server-Side Request Forgery (SSRF): la capacidad de hacer que el servidor de Capital One realizara peticiones HTTP a destinos que no debería. En este caso, al servicio de metadatos interno de AWS, que amablemente devolvió credenciales válidas para acceder a los datos almacenados en S3.
El SSRF escaló del puesto 10 al puesto 7 en el OWASP Top 10 de 2021, impulsado directamente por incidentes como el de Capital One. En la era cloud, donde los servidores conviven con servicios de metadatos que dispensan credenciales, un SSRF ya no es solo una vulnerabilidad web: es una puerta de entrada a toda la infraestructura.
¿Qué es un SSRF?
El concepto fundamental
Un SSRF ocurre cuando una aplicación web realiza peticiones HTTP (u otros protocolos) a URLs proporcionadas o influidas por el usuario, sin validación suficiente del destino. El servidor actúa como proxy involuntario del atacante, realizando peticiones a recursos que el atacante no podría alcanzar directamente.
┌──────────┐ 1. Petición con URL ┌──────────────┐
│ Atacante │ ────────────────────────→ │ Servidor │
│ │ │ (víctima) │
└──────────┘ └──────┬───────┘
│
2. El servidor │
hace la petición │
al destino ▼
┌──────────────┐
│ Recurso │
│ interno │
│ (metadata, │
│ DB, admin) │
└──────────────┘
La clave del SSRF es que el servidor tiene acceso a recursos que el atacante no tiene: redes internas, servicios de metadatos cloud, paneles de administración en localhost, bases de datos que solo aceptan conexiones locales.
Tipos de SSRF
SSRF básico (in-band). El atacante puede ver la respuesta del recurso interno directamente en la respuesta HTTP que recibe. Es el escenario más sencillo de explotar.
Ejemplo: una aplicación que permite previsualizar URLs externas.
GET /api/preview?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/
El servidor solicita esa URL interna y devuelve las credenciales IAM en la respuesta al atacante.
Blind SSRF (out-of-band). El atacante no ve la respuesta directa, pero puede inferir información:
- Por timing: si la petición a un puerto abierto tarda 200ms y a uno cerrado tarda 5s (timeout), el atacante puede escanear la red interna
- Por código HTTP: la aplicación devuelve 200 si el recurso existe, 500 si no
- Por exfiltración DNS: el atacante hace que el servidor resuelva un dominio controlado, registrando la IP de origen
Semi-blind SSRF. El atacante no ve el cuerpo de la respuesta pero sí metadatos como el tamaño, las cabeceras o el código de estado.
Dónde aparece el SSRF
El SSRF no se limita a un parámetro url evidente. Aparece en contextos menos obvios:
| Funcionalidad | Cómo se explota |
|---|---|
| Previsualización de URLs | El caso clásico: la aplicación fetch una URL para mostrar un preview |
| Generadores de PDF | Herramientas como wkhtmltopdf o Puppeteer que renderizan HTML a PDF pueden seguir enlaces internos |
| Procesamiento de imágenes | Resize, thumbnail o conversión de imágenes desde URL |
| Webhooks | La aplicación envía peticiones HTTP a URLs configuradas por el usuario |
| Import/export de datos | Importar datos desde URLs externas (feeds RSS, APIs) |
| Lectores de feeds XML | Parsers XML que resuelven DTDs o entities externas (XXE + SSRF) |
| Integraciones OAuth | Callbacks a URLs controladas por el usuario |
| Upload desde URL | Funcionalidad "importar desde URL" en vez de subir fichero |
Cloud metadata: el acelerador de impacto
El servicio de metadatos de instancia
Los proveedores cloud ejecutan un servicio HTTP interno en cada máquina virtual, accesible en la dirección IP de enlace local 169.254.169.254. Este servicio proporciona información sobre la instancia y, crucialmente, credenciales temporales del rol IAM asociado.
| Proveedor | URL de credenciales | Protección |
|---|---|---|
| AWS (IMDSv1) | http://169.254.169.254/latest/meta-data/iam/security-credentials/{role} | Ninguna (HTTP GET simple) |
| AWS (IMDSv2) | Mismo path, pero requiere token de sesión vía PUT previo | Token requerido |
| Azure | http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01 | Header Metadata: true requerido |
| GCP | http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token | Header Metadata-Flavor: Google requerido |
IMDSv1 de AWS era el más vulnerable: cualquier petición HTTP GET simple devolvía las credenciales. Sin cabeceras especiales, sin tokens, sin autenticación de ningún tipo.
De SSRF a compromiso total de la cuenta cloud
La cadena de ataque es directa:
SSRF Credenciales Acceso a
en la ────────────→ temporales ────────→ S3, RDS,
app web del rol IAM DynamoDB,
Lambda...
El impacto depende de los permisos del rol IAM. Si el rol tiene permisos amplios (como sucedió en Capital One), un solo SSRF equivale a acceso completo a los datos de la organización en la nube. Los permisos excesivos multiplican el daño de forma exponencial.
Capital One 2019: anatomía del ataque
La infraestructura vulnerable
Capital One, uno de los mayores emisores de tarjetas de crédito de Estados Unidos, había migrado agresivamente a AWS. Su infraestructura incluía:
- Un Web Application Firewall (WAF) desplegado como reverse proxy en instancias EC2
- Datos de clientes almacenados en buckets S3
- Un rol IAM (denominado "ISRM-WAF-Role") asociado a las instancias del WAF con permisos para acceder a múltiples buckets S3
El WAF tenía una configuración que permitía SSRF: aceptaba peticiones que podían redirigirse al servicio de metadatos interno.
La cadena de ataque
Paso 1: Descubrimiento del SSRF. Thompson, aprovechando su conocimiento de la infraestructura AWS (había trabajado en Amazon entre 2015 y 2016), identificó que el WAF de Capital One era vulnerable a SSRF.
Paso 2: Obtención de credenciales. A través del SSRF, realizó una petición al servicio de metadatos de AWS:
http://169.254.169.254/latest/meta-data/iam/security-credentials/ISRM-WAF-Role
El servicio devolvió credenciales temporales de AWS (AccessKeyId, SecretAccessKey, Token) asociadas al rol ISRM-WAF-Role.
Paso 3: Enumeración de buckets. Con las credenciales obtenidas, Thompson ejecutó comandos AWS CLI desde fuera de la red de Capital One:
# Listar buckets S3 accesibles con las credenciales robadas
aws s3 ls --profile stolen-creds
Encontró más de 700 buckets S3.
Paso 4: Exfiltración de datos. Descargó aproximadamente 30 GB de datos de múltiples buckets, incluyendo datos de solicitudes de tarjetas de crédito procesadas entre 2005 y 2019.
Paso 5: Detección (tardía). Thompson publicó los datos en GitHub el 21 de abril de 2019. Un investigador de seguridad lo descubrió y alertó a Capital One el 17 de julio. El FBI arrestó a Thompson el 29 de julio.
┌──────────────────────────────────────────────────────────────────┐
│ CAPITAL ONE BREACH: FLUJO DEL ATAQUE │
│ │
│ ┌─────────┐ SSRF ┌──────────┐ Creds ┌──────────────┐ │
│ │Thompson │ ────────→ │ WAF │ ───────→ │ AWS Metadata │ │
│ │(atacante)│ │ (EC2) │ │ (IMDSv1) │ │
│ └────┬─────┘ └──────────┘ └──────────────┘ │
│ │ │
│ │ Con credenciales IAM robadas │
│ │ │
│ ▼ │
│ ┌──────────┐ List + Download ┌────────────────────────┐ │
│ │ AWS CLI │ ──────────────────→ │ 700+ buckets S3 │ │
│ │ (fuera │ │ 106M registros │ │
│ │ de red) │ │ 140K SSN, 80K cuentas │ │
│ └──────────┘ └────────────────────────┘ │
└──────────────────────────────────────────────────────────────────┘
Las consecuencias
- 106 millones de registros de clientes expuestos (100M en EEUU, 6M en Canadá)
- 140.000 números de seguridad social y 80.000 números de cuenta bancaria
- Multa regulatoria de 80 millones de dólares del OCC (Office of the Comptroller of the Currency)
- Coste total estimado superior a 150 millones de dólares
- Thompson fue condenada en 2022 por fraude informático y robo de datos
Qué salió mal (y qué podría haberse evitado)
| Fallo | Mitigación que habría funcionado |
|---|---|
| WAF vulnerable a SSRF | Validación de URLs, bloqueo de rangos de IP internos |
| IMDSv1 sin protección | IMDSv2 (requiere token de sesión) |
| Rol IAM con permisos excesivos | Principio de mínimo privilegio, roles separados por función |
| Sin detección de exfiltración masiva | Alertas en CloudTrail por volumen anómalo de ListBucket/GetObject |
| Sin segmentación de red | Network ACLs que bloqueen acceso al metadata service desde la aplicación |
AWS publicó IMDSv2 en noviembre de 2019, parcialmente como respuesta a este incidente. IMDSv2 requiere un token de sesión obtenido mediante una petición PUT, lo que bloquea la mayoría de los SSRF porque las redirecciones HTTP no reenvían cabeceras personalizadas.
SSRF más allá de Capital One
Escaneo de redes internas
Un SSRF puede usarse para mapear la red interna de una organización. El atacante envía peticiones a rangos de IP internos (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) y observa las respuestas:
- Puerto abierto: respuesta rápida (200, 301, 403...)
- Puerto cerrado: connection refused rápido
- Host inexistente: timeout largo
Esto permite descubrir servicios internos: bases de datos Redis en el puerto 6379, Elasticsearch en 9200, paneles de administración en 8080, APIs internas sin autenticación.
SSRF en generadores de PDF
Las herramientas que convierten HTML a PDF (wkhtmltopdf, Puppeteer, WeasyPrint) son vectores de SSRF frecuentes. Si la aplicación permite al usuario proporcionar HTML o URLs que se renderizan en un PDF, un atacante puede incluir:
<iframe src="http://169.254.169.254/latest/meta-data/iam/security-credentials/"></iframe>
<img src="http://internal-admin-panel:8080/api/users">
<link rel="stylesheet" href="http://10.0.0.1:6379/INFO">
El generador de PDF, ejecutándose en el servidor, accede a esos recursos internos y los incluye en el PDF resultante. El atacante descarga el PDF y obtiene la información.
SSRF en procesadores de imágenes
Funcionalidades como "importar imagen desde URL" o "redimensionar imagen remota" son vectores clásicos. La aplicación descarga la imagen desde la URL proporcionada, pero el atacante proporciona una URL interna:
POST /api/resize
{"image_url": "http://169.254.169.254/latest/user-data"}
Algunos procesadores de imágenes (ImageMagick, por ejemplo) soportan protocolos adicionales como file://, ampliando la superficie de ataque a la lectura de ficheros locales del servidor.
SSRF en webhooks
Las aplicaciones SaaS que permiten configurar webhooks (notificaciones HTTP cuando ocurre un evento) son vulnerables si no validan la URL de destino. Un usuario malicioso configura un webhook apuntando a http://169.254.169.254/... y espera a que la aplicación dispare el evento.
DNS rebinding: evadiendo validaciones
Algunas aplicaciones validan la URL antes de realizar la petición: verifican que el dominio no resuelva a una IP interna. El DNS rebinding evade esta protección:
- El atacante registra un dominio con un TTL muy bajo (por ejemplo, 0 segundos)
- La primera resolución DNS apunta a una IP pública (pasa la validación)
- La segunda resolución (cuando el servidor hace la petición real) apunta a 169.254.169.254
- La validación pasó, pero la petición va al servicio de metadatos
Esta técnica funciona porque la validación y la petición son dos operaciones separadas en el tiempo, y el DNS puede cambiar entre ambas.
Prevención: defensa en profundidad
1. Validación de URLs (capa de aplicación)
La primera línea de defensa es validar estrictamente las URLs que la aplicación va a solicitar:
- Listas blancas de dominios: si la funcionalidad solo necesita acceder a dominios específicos, permitir solo esos
- Bloqueo de rangos IP internos: rechazar cualquier URL que resuelva a 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16, ::1
- Bloqueo de protocolos: permitir solo http:// y https://, bloquear file://, gopher://, dict://, ftp://
- Resolución DNS antes de la petición: resolver el dominio, verificar que la IP no es interna, y hacer la petición directamente a esa IP (no al dominio, para evitar DNS rebinding)
- Rechazar redirecciones: o validar cada destino de redirección con las mismas reglas
2. IMDSv2 y protecciones cloud
AWS: Forzar IMDSv2 en todas las instancias EC2. IMDSv2 requiere un token de sesión obtenido con PUT, con cabeceras personalizadas que no se reenvían en redirecciones HTTP.
# Forzar IMDSv2 en una instancia EC2
aws ec2 modify-instance-metadata-options \
--instance-id i-1234567890abcdef0 \
--http-tokens required \
--http-endpoint enabled
Azure: Ya requiere la cabecera Metadata: true por defecto, pero verificar que las aplicaciones no la incluyen en peticiones reenviadas.
GCP: Ya requiere la cabecera Metadata-Flavor: Google por defecto.
3. Segmentación de red
La defensa más robusta es de infraestructura: impedir que el servidor pueda alcanzar recursos que no necesita.
- Firewalls de salida (egress filtering): las instancias de aplicación solo pueden hacer peticiones salientes a destinos específicos
- Bloqueo del metadata service: si una instancia no necesita credenciales IAM vía metadata, bloquear el acceso a 169.254.169.254 con iptables o security groups
- VPC endpoints privados: acceder a servicios AWS (S3, DynamoDB) a través de endpoints VPC en lugar de Internet
4. Principio de mínimo privilegio en IAM
Incluso si un atacante obtiene credenciales temporales vía SSRF, el daño se limita a los permisos del rol:
- Roles IAM separados por función (no un rol para todo)
- Permisos específicos por bucket S3 (no
s3:*sobre todos los buckets) - Condiciones de red en las políticas IAM (solo desde IPs específicas)
5. Monitorización y detección
- CloudTrail: alertas por patrones anómalos de acceso (ListBuckets masivo, GetObject desde IPs no habituales)
- Accesos al IMDS: monitorizar frecuencia de peticiones al servicio de metadatos
- Peticiones salientes anómalas: detectar peticiones del servidor a rangos de IP internos no esperados
SSRF en el contexto de las aplicaciones modernas
La proliferación de arquitecturas de microservicios, APIs serverless y orquestadores de contenedores ha multiplicado la superficie de SSRF. Cada microservicio que acepta URLs como parámetro es un punto de entrada potencial. Kubernetes, con su API interna y tokens de servicio montados automáticamente en los pods, añade otra capa de recursos internos accesibles vía SSRF.
La combinación de SSRF con cloud es especialmente letal porque los servicios de metadatos convierten una vulnerabilidad web en acceso a infraestructura. Un SSRF en una aplicación on-premise es grave (escaneo de red, acceso a servicios internos). Un SSRF en una aplicación cloud con roles IAM mal configurados puede comprometer toda la cuenta.
Capital One perdió 106 millones de registros por un SSRF explotable con una sola petición HTTP. La lección es clara: en la era cloud, las vulnerabilidades web tienen consecuencias de infraestructura. La defensa requiere pensamiento de infraestructura, no solo validación de input.
Técnicas MITRE ATT&CK referenciadas
Preguntas frecuentes
Artículos relacionados
Este contenido tiene fines exclusivamente educativos y de investigación en ciberseguridad defensiva. No se proporcionan binarios maliciosos ni payloads ejecutables. El uso indebido de esta información es responsabilidad exclusiva del usuario. Leer disclaimer completo.