Host Header Injection + DoS en Microsoft

Camilo Galdos • August 30, 2025
Un fondo blanco con algunas líneas.

¿Qué es Host Header Injection?

El HTTP Header "Host", es la cabecera encargada de decirle al Web Server, cual es el virtual host que debe resolver al recibir el request de un cliente. El siguiente ejemplo es un uso clásico del header en un request:


GET /reset HTTP/1.1

Host: example.com


En la práctica, muchos frameworks utilizan el "Host" para hacer redirects, formar urls o enlaces que luego son usados en funciones (password reset, verificación), callbacks OAuth/OIDC, CORS y generación de links públicos.


El problema de confiar en los Header

El problema con las implementaciones que confían en el Host para realizar alguna función, es que a veces se olvidan que el Host puede ser modificado desde el cliente. Y que ese header muchas veces, hace distintos saltos y puede pasar por un  reverse proxy, load balancer o CDN que luego es reenviado (o normalizado). Una web vulnerable, al usar el valor de forma directa: 


<a href= "https://_SERVER['HOST']/password-reset" > Cambiar Contraseña </a>

Un atacante puede inyectar algo como:


GET /reset-password HTTP/1.1

Host: attacker.com


Y obligar a la aplicación a escribir en su front, URLs hacia su dominio como en el ejemplo, pero también, interceptar las rutas de la aplicación o envenenar cachés (cache poisoning). En esencia, ese es el Host Header Injection... cuando una aplicación utiliza el Header Host y el atacante lo modifica antes de ser usado. Esto ocurre más a menudo de lo que parece.


En este post expongo un caso real de Host Header Injection avanzado, encontrado y explotado en Xandr, el servicio B2B de Microsoft Ads. Primero explico como logré un open redirect, y posteriormente como lo convertí en un Denial of Service  que dejó la aplicación Inaccesible World Wide.


Vulnerability assesment

Como primer paso, forcé un Host header arbitrario para ver cómo reaccionaba la web, manteniendo el target real fijo en mi proxy (separando el Host header de la IP/puerto de destino para no “saltar” de servidor). Con el target apuntando al host legítimo, probé requests como:


GET /reset HTTP/1.1

Host: attacker.com


Si con un Host inesperado sigue funcionando la web, se puede inferir que hay un default/fallback virtual host y llega el momento de comenzar a observar qué hace el target con ese valor: ¿construye absolute URLs con Host?, ¿emite redirects basados en Host?, ¿altera routing o afecta caché?


Al momento de hacer cambio de "Host" puedes recibir inmediatamente "Invalid Host header" o su equivalente... Esto suele pasar cuando en la arquitectura hay reverse proxy / load balancer / CDN al frente de la web, en estos casos hay otras técnicas que te permiten cambiar el "Host" pero sin tener que cambiarlo directamente.



Explotación con Headers "Forwarded"

¿Qué es y por qué importa? La clave está en entender que estamos hablando de una vulnerabilidad que si bien impacta la aplicación web, se origina a nivel de protocolo. Las arquitecturas modernas casi siempre tienen saltos antes de llegar al backend real. Esto causa que el host a veces llegue modificado a su destino, esto puede ocurrir porque en algún "salto", algún asset del flujo, usa para la comunicación, un hostname local.


Dado que el backend en ocasiones requiere hacer un traceback y conocer el host original usado por el cliente, el protocolo HTTP ya ha implementado distintos headers que ayudan a realizar esta traza. Implementando esos headers, el backend sabe que host usar en las rutas.


X-Forwarded-Host  (XFH) es un header que el edge (reverse proxy/CDN/load balancer) debería fijar para que el back-end conozca el host público que vio en el borde (por ejemplo, dashboard.vulnerable.com). Esto es útil cuando el edge reenvía los requests con un "Host" interno, pero el endpoint necesita construir absolute URLs correctas (redirects, password reset, enlaces públicos). La siguiente ilustración explica de manera más didáctica el comportamiento explotando un Open Redirect. Nota: NO es X-Forwarded-For (XFF).

OPEN REDIRECT


Cualquier lógica del endpoint que construye absolute URLs terminó emitiendo enlaces basados en "Host":


  • Password reset hijack (links de reset hacia mi dominio).
  • Open redirect en flujos que dependen de absolute URLs.
  • Cache poisoning si hay caches que indexan por host.
  • Potencial SSRF en callbacks que confían en el host resultante.




Denial of Service - Incorrect Host Parsing

En este momento es donde se pone más interesante el hallazgo. Para que el Host Header Injection tenga un impacto importante, debe ser o muy específico y encontrarlo en un endpoint como los antes mencionados o sencillamente debe ser adherida a otra vulnerabilidad.


Cuando explotas un Host Header Injection, así como en SSRF u Open Redirect, casi siempre hay en el backend, un parser que no está funcionando de forma adecuada. Este caso, no fue la excepción. Durante las pruebas que realicé, encontré que si el valor de X-Forwarded-Host contenía ciertos caracteres con URL encode, la aplicación (Backend) generaba un error y el Edge contestaba con un Error 502.



Cuando enviaba el payload correcto para explotar la vulnerabilidad, el dominio completo de la aplicación de Microsoft, quedaba Off con un error 502 en el index. De hecho, el DoS duraba mayor cantidad de tiempo según el payload que se ponía como valor, en algunos casos por cada request enviado, el portal reflejaba a nivel mundial Error 502 Service Unavailable hasta por 30 segundos.


  • X-Forwarded-Host: %2e%2Fattacker.com (~10 segundos de DoS por request)


  • X-Forwarded-Host: %2e%2Fattacker.com%3A123 (~30 seconds de DoS por request)




Para subir el impacto de la aplicación hice un pequeño script en python que basicamente enviaba requests con el payload específico en el header X-Forwarded-Host de manera automática y mientras el exploit estaba en ejecución, el portal se veía con error 502 World Wide.



Buenas práticas y snippets

Para que puedan practicar la vulnerabilidad y en caso tengan una aplicación vulnerable, les dejo un pequeño snippet de código explicando como se ve la vulnerabilidad desde el código fuente. Desde los headers.


def get_base_url_vulnerable ():
# Se confia en el X-Forwarded-Host y lo usamos como host "público"
host = request.headers.get( "X-Forwarded-Host" , request.host)
#también confía en el scheme y aumenta muchísimo el riesgo.
scheme = request.headers.get( "X-Forwarded-Proto" , request.scheme)
return f" {scheme} :// {host} "

def go ():
# Redirect que construye el destino absoluto, con el URL base vulnerable
dest = f" {get_base_url_vulnerable()} /dashboard"
# Location quedará controlado por XFH si el edge/cliente lo fija
return redirect(dest, code= 302 )


(Referencial) - Recomendaciones:


  • No uses headers del cliente para el BASE_URL. Define el BASE_URL por entorno y consúltala desde un config file.


  • Si necesitas leer Host/X-Forwarded-Host, valida contra una allowlist y solo confía en headers seteados por tu reverse proxy/CDN (limpia los headers entrantes).


  • En el edge, no establezcas XFH → Host y fuerza canonical host (301/308) si llega uno no permitido.


Conclusiones

El caso presentado evidencia cómo una vulnerabilidad aparentemente menor, como confiar en el header "Host" puede convertirse en un vector crítico al interactuar con balanceadores, CDNs y parsers mal implementados. Lo que inició como un simple open redirect, aumentó considerablemente su impacto al escalar hasta un DoS global.


La lección que quisiera destacar es que la seguridad web no solo depende del código de la aplicación, también depende de cómo los distintos componentes de la arquitectura interactuan entre ellos y con los protocolos. Validar y controlar los headers entrantes, junto con una configuración segura en el edge, es indispensable para evitar que un detalle, se pueda transformar en un ataque de gran impacto. El hacking web moderno ya no es solo aplicación, también son protocolos.


Todos los Pentest realizados por el equipo de Deep Security, son ejecutados con un nivel técnico avalado por la experiencia de un equipo que reporta vulnerabilidades a las empresas más grandes del mundo.


Si necesitas un Pentest profesional y acompañamiento continuo para mantener segura la superficie en internet de tu compañía, escríbenos y nuestro equipo comercial te contactará.

.


24 de marzo de 2026
Análisis rápido Durante una revisión de la interfaz REST de administración de Payara Server se identificó una cadena de explotación en la que un XSS reflejado podía combinarse con un flujo inseguro de cambio de contraseña para derivar en takeover completo de la cuenta administrator. La severidad real del caso no estaba en una sola falla, sino en la forma en que varias decisiones de diseño reducían la resistencia del panel frente a ejecución de JavaScript en el mismo origen. El impacto no dependía únicamente del XSS. La cadena se volvía crítica por la combinación de cuatro elementos: - XSS reflejado en un endpoint administrativo - Cambio de contraseña sin validar la contraseña actual - Basic Auth enviada automáticamente por el navegador - Protección anti-CSRF débil basada en X-Requested-By En conjunto, esto permitía que un administrador autenticado, al visitar un enlace malicioso, terminara ejecutando una solicitud válida contra el endpoint de cambio de contraseña. Por esta vulnerabilidad me asignaron el CVE-2025-14340 XSS y el punto de entrada El primer componente era un XSS reflejado en el endpoint de versión de la consola: GET /management/domain/version?xss= HTTP/1.1 Host: panel.example.com:4848 En una consola de este tipo, un XSS no solo afecta la vista del usuario. También permite interactuar con funciones sensibles usando el mismo contexto autenticado del administrador. El CSRF que convierte el bug en takeover El segundo componente estaba en /management/domain/change-admin-password . De forma resumida, el flujo aceptaba una solicitud similar a esta: POST /management/domain/change-admin-password HTTP/1.1 Host: panel.example.com:4848 X-Requested-By: GlassFish REST HTML interface Content-Type: application/x-www-form-urlencoded id=admin&newpassword=[REDACTED]&password=[REDACTED] Lo problemático no era solo que cambiara credenciales, sino dos agravantes de diseño: No exigía la contraseña actual La “protección” anti-CSRF se basaba en X-Requested-By . Ese header funcionaba como una cabecera personalizada para marcar que la solicitud provenía del frontend esperado. El problema es que no era un control fuerte frente a JavaScript malicioso ejecutándose same-origin . ¿Header X-Requested-By ? X-Requested-By era, en la práctica, la señal que el backend utilizaba para distinguir una solicitud “esperada” de una solicitud arbitraria. La lógica era simple: si la request incluía la cabecera esperada, el servidor la trataba como legítima. Ese enfoque puede frenar algunos intentos externos básicos, pero deja de ser útil cuando un atacante consigue ejecutar JavaScript dentro del mismo origen de la consola. A nivel práctico, el comportamiento observado podía resumirse en un payload como la siguiente POC . fetch ( '/management/domain/change-admin-password' , { method: 'POST' , headers: { 'X-Requested-By' : 'GlassFish REST HTML interface' , 'Content-Type' : 'application/x-www-form-urlencoded' }, body: 'id=admin&newpassword=admin123&password=admin123' }); Y ahí aparecía el punto crítico de la cadena: el backend aceptaba una solicitud con la cabecera esperada, mientras el navegador adjuntaba automáticamente las credenciales administrativas mediante Basic Auth. https://panel.example.com:4848/management/domain/version?xss Full exploit: https://github.com/DeepSecurityResearch/CVE-2025-14340 Explotación y Same-Origin La explotación no dependía de una petición cross-origin convencional, sino de la ejecución de JavaScript dentro del mismo origen de la consola administrativa. ¿Por qué el CSRF solo es explotable mediante el XSS? Debido a que el endpoint usa Basic Authentication, explotarlo remotamente desde un origen externo es imposible: - CORS bloquea requests cross-origin al endpoint de administración - Basic Auth no puede forzarse desde otro dominio sin cooperación del navegador - El header X-Requested-By no puede añadirse en requests cross-origin Ese detalle era determinante. Una vez obtenido el XSS, el atacante podía interactuar con el endpoint de cambio de contraseña desde el mismo contexto que la interfaz legítima, incluyendo X-Requested-By y aprovechando el estado autenticado del administrador. En ese punto, el XSS dejaba de ser un hallazgo aislado y se convertía en la primitive necesaria para comprometer directamente la cuenta administrativa. Vectores de ataque Campaña de Phishing Dirigido Un atacante envía un email convincente con apariencia de "actualización de seguridad" que contiene el enlace malicioso. Cuando el administrador hace clic mientras está logueado, la contraseña se cambia silenciosamente. Watering Hole El atacante compromete un sitio interno frecuentemente visitado e inyecta un iframe invisible con el exploit. Al visitar el sitio, el exploit se ejecuta automáticamente en segundo plano sin indicación visible. Supply Chain Un atacante compromete la documentación de una herramienta usada por el equipo de operaciones. Al seguir un enlace de la documentación para troubleshooting, la cuenta queda comprometida. Capacidades del Atacante con acceso a la consola de administración: - Desplegar aplicaciones maliciosas (WAR/EAR files) - Modificar configuración del servidor - Acceder a datos de aplicaciones desplegadas - Crear mecanismos de persistencia - Extraer credenciales de datasources Conclusión CVE-2025-14340 demuestra cómo vulnerabilidades moderadas se convierten en críticas cuando se encadenan. Un XSS reflejado (severidad media) combinado con ausencia de protección CSRF (severidad baja-media) resultó en account takeover completo de administrador. La falla no residía únicamente en el XSS reflejado, sino en la forma en que esa primitive podía encadenarse con una operación sensible insuficientemente protegida. En este caso, el resultado final era claro: un XSS en contexto administrativo terminaba habilitando el takeover completo del administrador. Nota sobre el Coordinated Disclosure Esta vulnerabilidad fue reportada siguiendo prácticas de divulgación responsable. El período de coordinación de 113 días permitió al vendor desarrollar y desplegar un fix antes de la divulgación pública. Sin embargo, el proceso presentó desafíos. A pesar del compromiso inicial del vendor de coordinar la publicación del CVE y asegurar la atribución apropiada, la comunicación fue inconsistente. El CVE fue publicado sin la notificación prometida y sin la atribución acordada, situación que se corrigió posteriormente tras solicitarlo. Esta experiencia subraya la importancia de:  Políticas claras de disclosure Comunicación proactiva durante el proceso Respeto a los acuerdos de atribución Documentación exhaustiva de todas las interacciones
Gráfico oscuro con
por Camilo Galdos 4 de marzo de 2026
Análisis Rápido: XSS en Wayback Machine CVE-2025-58765
por Camilo Galdos 20 de febrero de 2026
 Introspecto r es un framework ofensivo diseñado para analizar y explotar comportamientos HTTP avanzados que ocurren “fuera” de la respuesta inmediata desde el servidor web (OOB - out of band). Más allá de un simple request/response, el objetivo es reconstruir la ruta de ejecución completa de un payload incluyendo patrones de redirección, resoluciones DNS, ejecución de solicitudes encadenadas y seguimiento de recursos servidos por el backend. En escenarios reales, muchas vulnerabilidades críticas no se manifiestan en el HTML de salida (response), sino en la infraestructura intermedia y el comportamiento del backend: balanceadores, reverse proxies, WAFs, CDN, resolvers DNS, caches, microservicios internos y clientes HTTP automatizados . Introspector está diseñado para capturar ese “lado invisible” del flujo, registrando redirecciones, reintentos, resoluciones DNS, follow-ups automáticos, y solicitudes encadenadas que pueden ocurrir segundos después y en hosts completamente distintos. Fue creada por el equipo de research de DeepSecurity específicamente para ir más allá de Burp Collaborator , permitiendo observar no solo si existe interacción OOB, sino cómo ocurre , qué componente la dispara, qué endpoint exacto la origina y qué cadena de ejecución se activa después (DNS, redirects, retries, fetches secundarios, etc.). En la práctica, Introspector ha sido utilizado tanto en proyectos con clientes como en iniciativas de research y bug bounty , sirviendo como base para hallazgos reales y reportes públicos, incluyendo Blind SSRF en Microsoft Ads , Host Header Injection + DoS en Microsoft , y vulnerabilidades CVE 2025 - 2026 reportadas responsablemente a plataformas como GlassFish y Payara . ¿Por qué usar Introspector en un pentest avanzado? Este tipo de visibilidad es clave para explotar y validar vulnerabilidades modernas como: SSRF (incluyendo SSRF ciego y SSRF con pivot a redes internas) Host Header Injection (en especial cuando la app construye URLs absolutas para resets de password, links de verificación, callbacks, etc.) Comportamientos anómalos en balanceadores / proxies (reescritura de Host, X-Forwarded-Host, X-Forwarded-Proto, Forwarded) HTTP Request Smuggling (cuando el front-end y back-end interpretan distinto Content-Length / Transfer-Encoding) Vulnerabilidades HTTP basadas en headers (cache poisoning, routing inconsistencies, internal URL generation, open redirect indirecto)
por Camilo Galdos 24 de julio de 2025
Server-Side Request Forgery para Pentesters
Un fondo azul con dos manos y las palabras
4 de septiembre de 2023
¿Por qué se siguen reportando incidentes en los Smart Contracts? Hay varias razones por las que los smart contracts siguen siendo un objetivo para un actor de amenaza, aca les mencionamos las principales.
Una langosta verde en una rama, y el mensaje de pruebas de penetración vs bug bounty
8 de agosto de 2023
Los programas de bug bounty (recompensas por errores) y penetration testing (pruebas de penetración son dos enfoques distintos para las pruebas de seguridad, cada uno con sus propios beneficios y consideraciones. Si bien algunos pueden verlos como métodos opuestos, en realidad pueden funcionar en conjunto para mejorar la postura de seguridad de una organización. Es importante comprender las diferencias entre los dos y evaluar qué enfoque se alinea mejor con las metas, el objetivo y los recursos específicos de la organización.
Un mapa azul de América del Sur tiene un fondo azul oscuro.
por DeepSecurity 24 de junio de 2020
SMBGhost (CVE-2020-0796) es una vulnerabilidad de ejecución remota de código, no autenticada, en Microsoft Server Message Block 3.1.1 (SMBv3). La vulnerabilidad sólo requiere que el puerto 445 esté abierto, y un atacante podría conectarse y ejecutar comandos sin necesidad de tener usuario o contraseña.
Un virus azul sobre fondo negro con las palabras reporte de ciberinteligencia
por DeepSecurity 1 de junio de 2020
Durante nuestras investigaciones de ciberinteligencia encontramos un grupo en Telegram donde se mencionan distintos temas desde hacking de aplicaciones web hasta robo de tarjetas (carding). Encontramos que algunos de los 550 ciberdelincuentes miembros de este grupo publicaban información sobre un fallo en la web del bono universal que permitía apropiarse del bono de los beneficiarios.
Una estatua de un oso está comiendo una hoja sobre un fondo negro.
por DeepSecurity 21 de mayo de 2020
El último año ha sido clave para la expansión digital de los bancos peruanos. Se han lanzado al mercado todo tipo de utilidades y aplicaciones que ayudan a las personas a gestionar su dinero de una manera más fácil. En DeepSecurity, nos preocupamos por la ciberseguridad del sistema financiero local y por eso hemos llevado a cabo un análisis pasivo (no-intrusivo) de las aplicaciones móviles de 12 bancos del Perú.
Una mano sostiene una pieza de ajedrez sobre un fondo azul.
por DeepSecurity 14 de abril de 2020
BlueKeep (CVE-2019-0708) es una vulnerabilidad de ejecución remota de código, no autenticada, en Remote Desktop Services (Servicio de RDP). La vulnerabilidad solo requiere que el puerto de RDP esté abierto y un atacante podría conectarse sin necesidad de tener usuario o contraseña.