IMDS (Instance Metadata Service) es una pieza crítica de la experiencia de AWS EC2: desde la instancia puedes consultar metadatos y, si hay un rol asociado (Instance Profile), obtener credenciales temporales para acceder a otros servicios. El problema no es la idea; el problema es IMDSv1: un endpoint HTTP accesible sin autenticación adicional desde la red local de la instancia. En la práctica, eso lo convierte en un objetivo perfecto cuando existe cualquier vector de SSRF (Server-Side Request Forgery).
Cuando esto pasa en una empresa, rara vez viene de “un servidor expuesto sin control”. Suele venir de algo mucho más mundano: una aplicación que hace fetch de URLs para generar previsualizaciones, un webhook que valida callbacks, un conector que integra SaaS, o un microservicio que permite apuntar a endpoints internos “por comodidad”. Si ese componente corre en EC2 con un rol con permisos útiles, IMDSv1 es el atajo hacia credenciales.
Qué salió mal: IMDSv1 y el supuesto de “solo es accesible desde la instancia”
IMDSv1 escucha en una IP link-local (169.254.169.254) accesible desde la instancia. En IMDSv1 no hay un desafío adicional (token) para evitar que un proceso engañado haga la petición. Si una aplicación dentro de esa instancia puede ser inducida a solicitar una URL arbitraria, ya tienes un puente hacia IMDS.
En entorno corporativo, el error típico no es “no sabíamos que existía IMDS”, sino tratarlo como un detalle de plataforma y delegar el riesgo a redes o a WAF. SSRF ignora muchos controles perimetrales porque el origen del tráfico es el propio servidor. Si el servidor tiene salida HTTP y la app permite forzar requests, el atacante no necesita conectividad directa a IMDS: la app hace el trabajo.
La consecuencia real es directa: el atacante consulta rutas del metadata service para enumerar el rol y extraer credenciales temporales. A partir de ahí, el incidente deja de ser “compromiso de una app” y pasa a ser “compromiso de AWS” en el ámbito de permisos del rol. Esto escala rápido cuando los roles de instancias se usan como identidad operativa para backups, deployment, acceso a S3, lectura de parámetros o incluso administración.
Cómo se materializa el abuso: SSRF tipo Capital One para llegar a credenciales
Un SSRF suele parecer inofensivo al principio: un endpoint que recibe una URL (para importar imágenes, validar un webhook, obtener un PDF) y devuelve contenido o solo un código de estado. Con IMDSv1, basta con poder hacer cualquier GET hacia 169.254.169.254 para empezar a obtener información útil. Aunque la respuesta no se muestre completa, muchas apps filtran trozos, registran contenido o permiten timing/oráculos suficientes para extraer datos.
En una cadena típica, el atacante primero “prueba agua” pidiendo metadatos básicos y luego va a por credenciales del rol. Una vez con credenciales temporales, la exploración pasa a AWS APIs: listar buckets, leer secretos, consultar parámetros, acceder a colas o volcar logs. El impacto depende del IAM del rol, no de la app; por eso en empresas el daño suele superar el perímetro del equipo que operaba esa aplicación.
- Enumeración del rol en la instancia
El atacante fuerza a la app a solicitar rutas del metadata service hasta identificar el nombre del rol (por ejemplo, consultando el path de roles IAM en metadatos). En operaciones reales, esto se ve como un patrón de requests internos anómalos desde el propio proceso de la app o desde librerías HTTP genéricas que “de repente” empiezan a hablar con 169.254.169.254.
- Exfiltración de credenciales temporales y uso fuera de la instancia
Con el nombre del rol, el siguiente paso es solicitar el documento de credenciales (AccessKeyId/SecretAccessKey/Token). Aunque sean temporales, suelen durar lo suficiente para operar. En incidentes corporativos, el atacante las usa desde su infraestructura para llamar a AWS APIs, lo que complica la atribución si no tienes CloudTrail bien instrumentado y alertas de uso “desde fuera” (nuevos IPs, nuevos user-agents, cambios de región).
Por qué IMDSv2 cambia el juego: tokens, sesiones y fricción real contra SSRF
IMDSv2 introduce un mecanismo de sesión basado en token (PUT para obtener token con TTL, luego GET incluyendo el token). Esto no es “seguridad por oscuridad”; es una barrera concreta frente a SSRF porque obliga a que el cliente pueda realizar una petición adicional y gestionar cabeceras. Muchos SSRF no permiten controlar método/headers, o solo permiten GET simples. Ese pequeño requisito rompe una enorme cantidad de vectores reales.
En la práctica, IMDSv2 no hace imposible el abuso en todos los escenarios (hay SSRF avanzados que permiten métodos y cabeceras), pero eleva el coste y reduce el número de rutas explotables. En empresas, esto se traduce en una reducción significativa del riesgo sistémico: una clase de bugs frecuentes deja de ser automáticamente “robo de credenciales cloud”.
- La mejora no es teórica: reduce el “blast radius” de vulnerabilidades comunes
SSRF aparece en revisiones de seguridad con más frecuencia de la que nos gustaría, especialmente en servicios internos con integraciones. Forzar IMDSv2 convierte muchas de esas findings en un problema de aplicación (grave, sí) pero no necesariamente en acceso a credenciales IAM. Esa diferencia cambia la severidad, la urgencia de contención y el alcance del incidente.
- IMDSv1 mantiene una puerta abierta permanente
El riesgo de IMDSv1 no depende de “si hoy hay SSRF”. Depende de que algún día aparezca uno (en tu código, en una librería, en un componente legado, en un endpoint olvidado). En entornos corporativos con ciclos largos y múltiples equipos, asumir que no habrá SSRF es apostar contra la estadística.
Cómo hacerlo en la práctica: forzar IMDSv2 y validar que IMDSv1 no está disponible
Operativamente, el objetivo es que las instancias EC2 funcionen con IMDSv2 requerido (no “opcional”) y, cuando sea posible, reducir la exposición del metadata service. Esto se gestiona a nivel de instancia o plantilla de lanzamiento (Launch Template) y debe formar parte del estándar de plataforma, no de una excepción por equipo.
El error común en empresas es “habilitamos IMDSv2” pero lo dejamos en modo optional para no romper nada. Eso mantiene IMDSv1 vivo. Si quieres cerrar la vía rápida a credenciales mediante SSRF básico, necesitas require. Cuando algo se rompe, normalmente revela dependencias antiguas (scripts de bootstrap, agentes, AMIs legacy) que conviene arreglar, no perpetuar.
Configuración esperada (a nivel de instancia o Launch Template):
- HttpTokens = required
- HttpEndpoint = enabled (si lo necesitas; si no, deshabilitarlo en casos concretos reduce superficie)
- HttpPutResponseHopLimit ajustado (por defecto suele ser suficiente; revisa si tienes proxies/sidecars que puedan acceder a IMDS)
Cada punto tiene impacto operativo: required obliga a librerías/herramientas a soportar IMDSv2; endpoint determina si existe el servicio; y el hop limit influye en si componentes en red “intermedia” pueden alcanzar el metadata service. En arquitecturas con proxies locales o configuraciones de red complejas, este último parámetro puede evitar accesos no deseados desde componentes que no deberían tocar metadatos.
Validación en AWS: revisa en la consola de EC2 (Instance details → Metadata options) que IMDSv2: required está aplicado. A nivel de inventario, usa AWS CLI para auditar flotas:
aws ec2 describe-instances --query "Reservations[].Instances[].MetadataOptions"
En incident response y hardening continuo, esto te permite detectar rápidamente instancias que siguen en IMDSv1 (tokens optional) y priorizar. La evidencia práctica es binaria: si tokens no son required, el vector IMDSv1 sigue existiendo.
Recomendaciones para entornos corporativos
IMDSv1 es peligroso porque convierte un SSRF relativamente común en una vía directa hacia credenciales temporales del rol de la instancia. En empresa, eso suele amplificar el incidente desde una aplicación a múltiples recursos en AWS, condicionado únicamente por los permisos IAM asignados al Instance Profile.
Forzar IMDSv2 (tokens required) introduce fricción real contra SSRF y reduce drásticamente el número de escenarios explotables. La medida es concreta, verificable y debe gestionarse como estándar de plataforma: en Launch Templates, en AMIs base y en auditorías periódicas que detecten excepciones.
La práctica que mejor funciona es tratar IMDSv1 como deuda técnica con riesgo de seguridad: identificar instancias con tokens optional, corregir dependencias que impiden IMDSv2 y validar continuamente que el cambio permanece aplicado. El objetivo no es “cumplir”, es evitar que el próximo SSRF termine en credenciales AWS fuera de control.
¿Te interesa la seguridad en Cloud?
Comparto análisis técnicos, laboratorios prácticos y experiencias reales sobre Cloud Security.