Pentesting
web cache poisoning
pentesting
Burp Suite

Web Cache Poisoning: envenenamiento de caché web

Web cache poisoning: cómo los inputs no incluidos en la cache key (X-Forwarded-Host, fat GET) envenenan cachés HTTP/CDN y se encadenan con XSS y open.

Secra6 de julio de 202610 min de lectura

El web cache poisoning (envenenamiento de caché web) es una técnica ofensiva que convierte un caché legítimo en un mecanismo de distribución de payloads. En lugar de atacar directamente a una víctima, el atacante logra que una capa de caché (una CDN, un reverse proxy como Varnish o Nginx, o el propio caché de la aplicación) almacene una respuesta maliciosa y la sirva después a todos los usuarios que soliciten esa misma URL. Un único payload bien colocado puede afectar a miles de peticiones, y ahí reside su gravedad. En este artículo lo analizamos desde la perspectiva del pentester: cómo se descubren los inputs explotables, cómo se confirma el impacto y cómo se encadena con otras vulnerabilidades.

Conviene aclararlo desde el principio: hablamos de caché de capa de aplicación (HTTP), no de envenenamiento de caché DNS ni de ARP. Son ataques con nombre parecido pero de capas distintas, y lo detallamos más abajo.

Qué es el web cache poisoning

Un caché web guarda copias de respuestas para servirlas rápido sin volver a molestar al servidor de origen. Para decidir si dos peticiones son "la misma" y pueden compartir respuesta, el caché calcula una cache key (clave de caché). El ataque consiste en encontrar un componente de la petición que:

  1. Influye en el contenido de la respuesta que genera el origen.
  2. No forma parte de la cache key, por lo que el caché lo ignora al indexar.

A ese componente se le llama input no incluido en la clave (unkeyed input). Si el atacante envía una petición con un unkeyed input malicioso, el origen genera una respuesta contaminada, el caché la almacena bajo la clave "limpia" de la URL y, a partir de ese momento, la sirve a víctimas que ni siquiera enviaron esa cabecera.

Es una variante de las vulnerabilidades de configuración e inyección que repasamos en las 5 vulnerabilidades web más comunes, pero con un multiplicador de alcance: el caché reparte el payload por nosotros.

La cache key y los inputs no incluidos en la clave

Qué compara realmente un caché

Por defecto, la mayoría de cachés construyen la clave con el método HTTP, el host y la ruta con su query string. Es decir, GET https://tienda.com/producto?id=5 suele ser una clave completa. Lo interesante para el atacante es todo lo que queda fuera de esa clave y aun así llega al origen:

  • Cabeceras como X-Forwarded-Host, X-Forwarded-Scheme, X-Forwarded-Proto, X-Host, X-Original-URL o X-Forwarded-Server.
  • Cabeceras personalizadas que introduce el framework o el balanceador.
  • Parámetros de query que el caché decide excluir de la clave (por ejemplo, utm_source y otros parámetros de tracking, o parámetros que la aplicación considera irrelevantes).

Inputs no keyed: la superficie de ataque

La cabecera Vary permite al origen indicar qué cabeceras deben formar parte de la clave (típicamente Accept-Encoding o Accept-Language). Todo lo que no esté en Vary ni en la clave por defecto es un candidato a unkeyed input. El primer paso de una auditoría de web cache poisoning es, por tanto, cartografiar qué entradas afectan a la respuesta sin afectar a la clave.

Vectores desde una perspectiva ofensiva

X-Forwarded-Host y cabeceras de proxy reflejadas

El caso clásico, documentado por James Kettle en su investigación "Practical Web Cache Poisoning" (PortSwigger, 2018), es una aplicación que construye URLs absolutas a partir de X-Forwarded-Host. Muchos frameworks confían en esa cabecera para generar enlaces canónicos, importar recursos o formar rutas de scripts:

GET / HTTP/1.1
Host: victima.com
X-Forwarded-Host: atacante.com

Si la respuesta refleja el valor sin validarlo, el origen puede devolver algo como:

<script src="https://atacante.com/static/analytics.js"></script>

Una vez cacheada, esa respuesta hace que cualquier visitante cargue JavaScript controlado por el atacante: un XSS almacenado de facto servido por el propio caché. La variante con X-Forwarded-Scheme: nothttps o X-Forwarded-Proto puede forzar redirecciones (301/302) hacia el atacante o bucles de redirección que degradan el servicio.

Fallos de normalización de la cache key

El caché y el origen no siempre interpretan una URL igual. Si el caché normaliza la clave (decodifica %2F, ignora mayúsculas, recorta el fragmento o elimina ciertos caracteres) de forma distinta a como el origen procesa la ruta, el atacante puede envenenar una clave que el caché considera equivalente a la URL de la víctima. Kettle amplió estos escenarios en "Web Cache Entanglement" (2020), donde demuestra que las inconsistencias de parsing entre capas son una fuente inagotable de claves colisionables.

Fat GET y parámetros no incluidos en la clave

Un fat GET es una petición GET que transporta parámetros en el cuerpo. Algunos frameworks los procesan aunque el método sea GET, mientras que el caché solo indexa la query string. Resultado: dos peticiones con la misma clave pero distinto cuerpo, una de ellas envenenada. El mismo principio se aplica a los parámetros de query excluidos de la clave: si el caché descarta lang al calcular la clave pero el origen lo usa para renderizar contenido, ese parámetro se convierte en un vector. Estos abusos de la semántica de parámetros comparten filosofía con los defectos de lógica de negocio: el sistema hace exactamente lo que le pides, pero nadie previó esa combinación.

Encadenar el envenenamiento: XSS, open redirect y DoS

El web cache poisoning rara vez es el impacto final: es el amplificador. Los encadenamientos más habituales en una auditoría son:

  • XSS reflejado a XSS masivo. Un parámetro o cabecera que se reflejaba en la respuesta y que, aislado, requería que la víctima hiciera clic en un enlace preparado, pasa a servirse a todos los usuarios de la URL cacheada. El cross-site scripting deja de necesitar interacción por víctima.
  • Open redirect masivo. Si la respuesta cacheada redirige en función de una cabecera reflejada, todo el tráfico de esa ruta acaba en el dominio del atacante, útil para phishing o robo de tokens OAuth.
  • Importación de recursos. Envenenar el src de un script, un import de CSS o un <base href> permite cargar código externo con la confianza del dominio legítimo.
  • Cache-Poisoned DoS (CPDoS). Descrito por Nguyen y Lo Iacono en 2019, consiste en enviar una cabecera malformada (oversize, con metacaracteres o con X-HTTP-Method-Override) que hace que el origen devuelva un 400 o 404, y el caché almacena ese error, denegando el servicio a los usuarios legítimos.
GET / HTTP/1.1
Host: victima.com
X-Metachar-Header: %00

En el pentest, la combinación con SSRF o con problemas del OWASP Top 10 2025 suele elevar la severidad de "reflejo curioso" a "compromiso de todos los usuarios de la ruta".

Detección con Burp Suite y Param Miner

El flujo de trabajo estándar para cazar web cache poisoning combina reconocimiento manual y automatización con Burp Suite:

  1. Identificar el caché. Buscar en las respuestas cabeceras como Age, X-Cache: hit/miss, CF-Cache-Status, X-Served-By o tiempos de respuesta que caen bruscamente en la segunda petición.
  2. Usar un cache buster. Añadir un parámetro único (?cb=837462) a la URL durante las pruebas. Es una regla de oro: aísla tu clave para no envenenar a usuarios reales de producción mientras investigas.
  3. Descubrir unkeyed inputs con Param Miner. La extensión de PortSwigger dispone de "Guess headers" y "Guess GET/POST params": envía cientos de cabeceras y parámetros conocidos con un cache buster incorporado y reporta cuáles influyen en la respuesta sin formar parte de la clave.
  4. Confirmar la persistencia. Enviar la petición envenenada, luego repetirla sin la cabecera maliciosa (misma clave) y comprobar que la respuesta contaminada se sirve desde el caché.

Este enfoque metódico es el mismo que aplicamos en cualquier auditoría web y móvil: reproducir el hallazgo, medir el radio de impacto y documentar la clave exacta que queda envenenada.

Web cache poisoning no es DNS ni ARP cache poisoning

Es una confusión habitual por el nombre compartido, así que conviene separarlo con claridad:

  • DNS cache poisoning. Corrompe el caché de un resolver DNS para que un dominio apunte a una IP del atacante (el ataque de Kaminsky es el ejemplo canónico). Opera sobre la resolución de nombres, no sobre HTTP.
  • ARP cache poisoning. Es un ataque de capa 2 dentro de una LAN: falsea la tabla ARP para situarse como intermediario (man in the middle) entre dos hosts. Es un vector de sniffing y spoofing en red local.
  • Web cache poisoning. Actúa en la capa 7 (aplicación), sobre cachés HTTP como CDNs, reverse proxies o el caché del navegador. Ni toca DNS ni la capa de enlace.

La diferencia práctica para el auditor es el conjunto de herramientas: aquí no hay ettercap ni suplantación de resolvers, sino Burp Suite, análisis de cabeceras HTTP y comprensión fina de cómo cada CDN calcula su clave.

Cómo se defiende una organización

Desde el lado defensivo, las contramedidas son directas una vez entendido el mecanismo:

  • Tratar X-Forwarded-Host y todas las cabeceras X-Forwarded-* como entrada no confiable: no reflejarlas nunca en la respuesta sin validación estricta.
  • Incluir en la cache key todo input que afecte a la respuesta, o eliminarlo en el edge antes de que llegue al origen.
  • Configurar Vary de forma correcta y desactivar el cacheo de respuestas dinámicas o específicas de usuario.
  • Normalizar la clave de manera consistente entre caché y origen para evitar colisiones de parsing.

Preguntas frecuentes

¿En qué se diferencia el web cache poisoning del web cache deception?

Son primos, pero opuestos. El poisoning inyecta una respuesta maliciosa en el caché para servirla a otros. El web cache deception engaña al caché para que almacene una respuesta privada de una víctima (por ejemplo, su página de perfil) en una URL que el atacante puede recuperar después. Uno reparte payloads, el otro roba datos sensibles.

¿Qué es exactamente un unkeyed input?

Es cualquier componente de la petición que modifica la respuesta del origen pero que el caché no incluye al calcular su clave. Cabeceras como X-Forwarded-Host, parámetros de query excluidos de la clave o el cuerpo de un fat GET son ejemplos típicos. Son la superficie de ataque principal del web cache poisoning.

¿Sirve Param Miner para detectar todos los casos?

Param Miner automatiza el descubrimiento de cabeceras y parámetros no keyed que se reflejan en la respuesta, que cubre la mayoría de casos habituales. No sustituye al análisis manual de fallos de normalización de clave ni de inconsistencias de parsing entre caché y origen, donde hace falta razonar sobre cada capa por separado.

¿Un WAF frena el envenenamiento de caché?

Solo parcialmente. Un WAF puede bloquear payloads XSS evidentes, pero no resuelve el problema de fondo: que un input no confiable llegue al origen y quede fuera de la cache key. La corrección real está en la configuración del caché y en no reflejar cabeceras de proxy.


En Secra auditamos cachés HTTP, CDNs y reverse proxies dentro del servicio de auditoría web y móvil, con foco en unkeyed inputs, normalización de claves y encadenamiento con XSS, open redirect y CPDoS. Cada hallazgo llega con reproducción, la clave exacta envenenada, la severidad justificada por impacto de negocio y un plan de remediación priorizado. Si quieres una propuesta para tu aplicación, escríbenos desde contacto.

Sobre el autor

Equipo de Secra Solutions

Ethical hackers certificados OSCP, OSEP, OSWE, CRTO, CRTL y CARTE, con más de 7 años de experiencia en ciberseguridad ofensiva. Autores de los CVE-2025-40652 y CVE-2023-3512.

Compartir artículo