Encabezados HTTP especiales
Reading time: 12 minutes
tip
Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Hacking en Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.
Wordlists & Tools
- https://github.com/danielmiessler/SecLists/tree/master/Miscellaneous/Web/http-request-headers
- https://github.com/rfc-st/humble
Headers to Change Location
Reescribir fuente IP:
X-Originating-IP: 127.0.0.1
X-Forwarded-For: 127.0.0.1
X-Forwarded: 127.0.0.1
Forwarded-For: 127.0.0.1
X-Forwarded-Host: 127.0.0.1
X-Remote-IP: 127.0.0.1
X-Remote-Addr: 127.0.0.1
X-ProxyUser-Ip: 127.0.0.1
X-Original-URL: 127.0.0.1
Client-IP: 127.0.0.1
X-Client-IP: 127.0.0.1
X-Host: 127.0.0.1
True-Client-IP: 127.0.0.1
Cluster-Client-IP: 127.0.0.1
Via: 1.0 fred, 1.1 127.0.0.1
Connection: close, X-Forwarded-For
(Revisar hop-by-hop headers)
Reescribir ubicación:
X-Original-URL: /admin/console
X-Rewrite-URL: /admin/console
Cabeceras hop-by-hop
Una cabecera hop-by-hop es una cabecera diseñada para ser procesada y consumida por el proxy que está manejando actualmente la petición, a diferencia de una cabecera end-to-end.
Connection: close, X-Forwarded-For
HTTP Request Smuggling
Content-Length: 30
Transfer-Encoding: chunked
HTTP Request Smuggling / HTTP Desync Attack
El header Expect
Es posible que el cliente envíe la cabecera Expect: 100-continue
y entonces el servidor responda con HTTP/1.1 100 Continue
para permitir que el cliente continúe enviando el body de la petición. Sin embargo, a algunos proxies no les gusta esta cabecera.
Resultados interesantes de Expect: 100-continue
:
- Enviar una petición HEAD con un body: el servidor no tuvo en cuenta que las peticiones HEAD no llevan body y mantiene la conexión abierta hasta que ocurre un timeout.
- Algunos servidores devolvieron datos extraños: datos aleatorios leídos del socket en la respuesta, claves secretas o incluso permitió que el front-end no eliminara valores de cabeceras.
- También causó una desincronización
0.CL
porque el backend respondió con un 400 en lugar de un 100, pero el proxy front-end estaba preparado para enviar el body de la petición inicial, así que lo envía y el backend lo toma como una nueva petición. - Enviar una variación como
Expect: y 100-continue
también provocó la desincronización0.CL
. - Un error similar donde el backend respondió con un 404 generó una desincronización
CL.0
porque la petición maliciosa indicaba unContent-Length
, así que el backend envía la petición maliciosa + los bytes delContent-Length
de la siguiente petición (de una víctima). Esto desincroniza la cola porque el backend envía la respuesta 404 para la petición maliciosa + la respuesta de las peticiones de la víctima, pero el front-end pensó que solo se había enviado 1 petición, por lo que la segunda respuesta se envía a una segunda petición de la víctima y la respuesta de esa se envía a la siguiente...
Para más información sobre HTTP Request Smuggling consulta:
HTTP Request Smuggling / HTTP Desync Attack
Cabeceras de caché
Cabeceras de caché del servidor:
X-Cache
en la respuesta puede tener el valormiss
cuando la petición no fue cacheada y el valorhit
cuando sí lo está.- Comportamiento similar en la cabecera
Cf-Cache-Status
. Cache-Control
indica si un recurso está siendo cacheado y cuándo será la siguiente vez que el recurso se considere válido:Cache-Control: public, max-age=1800
Vary
se usa a menudo en la respuesta para indicar cabeceras adicionales que se tratan como parte de la clave de caché aunque normalmente no estén incluidas.Age
define los segundos que el objeto ha estado en la caché del proxy.Server-Timing: cdn-cache; desc=HIT
también indica que un recurso fue cacheado.
Cache Poisoning and Cache Deception
Cabeceras de caché local:
Clear-Site-Data
: Cabecera para indicar qué cachés deben eliminarse:Clear-Site-Data: "cache", "cookies"
Expires
: Contiene la fecha/hora en la que la respuesta debería expirar:Expires: Wed, 21 Oct 2015 07:28:00 GMT
Pragma: no-cache
igual queCache-Control: no-cache
Warning
: El encabezado general HTTPWarning
contiene información sobre posibles problemas con el estado del mensaje. Puede aparecer más de una cabeceraWarning
en una respuesta.Warning: 110 anderson/1.3.37 "Response is stale"
Condicionales
- Las peticiones que usan estas cabeceras:
If-Modified-Since
yIf-Unmodified-Since
recibirán datos solo si la cabecera de respuestaLast-Modified
contiene una hora diferente. - Las peticiones condicionales que usan
If-Match
yIf-None-Match
usan un valor Etag para que el servidor envíe el contenido de la respuesta si los datos (Etag) han cambiado. ElEtag
se toma de la respuesta HTTP. - El valor Etag suele calcularse en base al contenido de la respuesta. Por ejemplo,
ETag: W/"37-eL2g8DEyqntYlaLp5XLInBWsjWI"
indica que elEtag
es el Sha1 de 37 bytes.
Range requests
Accept-Ranges
: Indica si el servidor soporta range requests, y si es así en qué unidad puede expresarse el rango.Accept-Ranges: <range-unit>
Range
: Indica la parte de un documento que el servidor debe devolver. Por ejemplo,Range:80-100
devolverá los bytes 80 a 100 de la respuesta original con un código 206 Partial Content. También recuerda eliminar la cabeceraAccept-Encoding
de la petición.- Esto puede ser útil para obtener una respuesta con código JavaScript reflejado arbitrario que de otro modo podría ser escapado. Pero para abusar de esto necesitarías inyectar estas cabeceras en la petición.
If-Range
: Crea una petición de rango condicional que solo se cumplirá si el etag o la fecha proporcionados coinciden con el recurso remoto. Usado para evitar descargar dos rangos de versiones incompatibles del recurso.Content-Range
: Indica dónde pertenece un mensaje parcial dentro de un mensaje de cuerpo completo.
Información del cuerpo del mensaje
Content-Length
: El tamaño del recurso, en número decimal de bytes.Content-Type
: Indica el tipo de medio del recurso.Content-Encoding
: Usado para especificar el algoritmo de compresión.Content-Language
: Describe el(los) idioma(s) humano(s) destinados a la audiencia, permitiendo diferenciar según el idioma preferido del usuario.Content-Location
: Indica una ubicación alternativa para los datos devueltos.
Desde un punto de vista pentest esta información suele ser "inútil", pero si el recurso está protegido por un 401 o 403 y puedes encontrar alguna manera de obtener esta info, esto podría ser interesante.
Por ejemplo, una combinación de Range
y Etag
en una petición HEAD puede leak el contenido de la página vía peticiones HEAD:
- Una petición con la cabecera
Range: bytes=20-20
y con una respuesta que contieneETag: W/"1-eoGvPlkaxxP4HqHv6T3PNhV9g3Y"
está leakando que el SHA1 del byte 20 esETag: eoGvPlkaxxP4HqHv6T3PNhV9g3Y
Información del servidor
Server: Apache/2.4.1 (Unix)
X-Powered-By: PHP/5.3.3
Controles
Allow
: Esta cabecera se usa para comunicar los métodos HTTP que un recurso puede manejar. Por ejemplo, puede especificarse comoAllow: GET, POST, HEAD
, indicando que el recurso soporta esos métodos.Expect
: Utilizado por el cliente para transmitir expectativas que el servidor debe cumplir para que la petición sea procesada con éxito. Un caso común es la cabeceraExpect: 100-continue
, que indica que el cliente pretende enviar una carga de datos grande. El cliente espera una respuesta100 (Continue)
antes de proceder con la transmisión. Este mecanismo ayuda a optimizar el uso de la red esperando la confirmación del servidor.
Descargas
- La cabecera
Content-Disposition
en respuestas HTTP indica si un archivo debe mostrarse inline (dentro de la página web) o tratarse como un attachment (descargado). Por ejemplo:
Content-Disposition: attachment; filename="filename.jpg"
Esto significa que el archivo llamado "filename.jpg" está destinado a ser descargado y guardado.
Encabezados de seguridad
Content Security Policy (CSP)
Content Security Policy (CSP) Bypass
Trusted Types
Al aplicar Trusted Types mediante CSP, las aplicaciones pueden protegerse contra ataques DOM XSS. Trusted Types garantizan que solo objetos específicamente creados, conformes con políticas de seguridad establecidas, puedan utilizarse en llamadas a APIs web peligrosas, asegurando así el código JavaScript por defecto.
// Feature detection
if (window.trustedTypes && trustedTypes.createPolicy) {
// Name and create a policy
const policy = trustedTypes.createPolicy('escapePolicy', {
createHTML: str => str.replace(/\</g, '<').replace(/>/g, '>');
});
}
// Assignment of raw strings is blocked, ensuring safety.
el.innerHTML = "some string" // Throws an exception.
const escaped = policy.createHTML("<img src=x onerror=alert(1)>")
el.innerHTML = escaped // Results in safe assignment.
X-Content-Type-Options
Este header previene MIME type sniffing, una práctica que podría conducir a vulnerabilidades XSS. Garantiza que los navegadores respeten los MIME types especificados por el servidor.
X-Content-Type-Options: nosniff
X-Frame-Options
Para combatir clickjacking, esta cabecera restringe cómo se pueden incrustar los documentos en <frame>
, <iframe>
, <embed>
o <object>
, recomendando que todos los documentos especifiquen explícitamente sus permisos de incrustación.
X-Frame-Options: DENY
Cross-Origin Resource Policy (CORP) y Cross-Origin Resource Sharing (CORS)
CORP es crucial para especificar qué recursos pueden ser cargados por los sitios web, mitigando cross-site leaks. CORS, por otro lado, permite un mecanismo más flexible de compartición de recursos entre orígenes, relajando la política de mismo origen bajo ciertas condiciones.
Cross-Origin-Resource-Policy: same-origin
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true
Cross-Origin Embedder Policy (COEP) y Cross-Origin Opener Policy (COOP)
COEP y COOP son esenciales para habilitar el aislamiento entre orígenes, reduciendo significativamente el riesgo de ataques similares a Spectre. Controlan, respectivamente, la carga de recursos de origen cruzado y la interacción con ventanas de origen cruzado.
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin-allow-popups
HTTP Strict Transport Security (HSTS)
Por último, HSTS es una característica de seguridad que obliga a los navegadores a comunicarse con los servidores únicamente a través de conexiones HTTPS seguras, mejorando así la privacidad y la seguridad.
Strict-Transport-Security: max-age=3153600
Header Name Casing Bypass
HTTP/1.1 define los nombres de campos de cabecera como insensibles a mayúsculas/minúsculas (RFC 9110 §5.1). No obstante, es muy común encontrar middleware personalizado, filtros de seguridad o lógica de negocio que comparan el nombre de cabecera literal recibido sin normalizar antes el uso de mayúsculas/minúsculas (p. ej. header.equals("CamelExecCommandExecutable")
). Si esas comprobaciones se realizan sensible a mayúsculas/minúsculas, un atacante puede omitirlas simplemente enviando la misma cabecera con una capitalización diferente.
Situaciones típicas en las que aparece este error:
- Custom allow/deny lists que intentan bloquear cabeceras internas “peligrosas” antes de que la petición llegue a un componente sensible.
- Implementaciones internas de pseudo-cabeceras de reverse-proxy (p.ej.
X-Forwarded-For
sanitisation). - Frameworks que exponen endpoints de management / debug y dependen de los nombres de cabecera para la autenticación o la selección de comandos.
Abusar del bypass
- Identificar una cabecera que sea filtrada o validada en el servidor (por ejemplo, leyendo código fuente, documentación o mensajes de error).
- Enviar la misma cabecera con una capitalización diferente (mixed-case o upper-case). Debido a que las pilas HTTP suelen canonicalizar las cabeceras sólo después de que se ejecute el código de usuario, la comprobación vulnerable puede evitarse.
- Si el componente downstream trata las cabeceras de forma insensible a mayúsculas/minúsculas (la mayoría lo hace), aceptará el valor controlado por el atacante.
Example: Apache Camel exec
RCE (CVE-2025-27636)
En versiones vulnerables de Apache Camel las rutas del Command Center intentan bloquear peticiones no confiables eliminando las cabeceras CamelExecCommandExecutable
y CamelExecCommandArgs
. La comparación se hacía con equals()
por lo que sólo los nombres exactamente en la forma esperada eran eliminados.
# Bypass the filter by using mixed-case header names and execute `ls /` on the host
curl "http://<IP>/command-center" \
-H "CAmelExecCommandExecutable: ls" \
-H "CAmelExecCommandArgs: /"
Las cabeceras llegan al componente exec
sin filtrarse, resultando en remote command execution con los privilegios del proceso Camel.
Detección y mitigación
- Normalice todos los nombres de cabecera a un único caso (normalmente minúsculas) antes de realizar comparaciones allow/deny.
- Rechace duplicados sospechosos: si están presentes tanto
Header:
comoHeAdEr:
, trátelo como una anomalía. - Utilice una allow-list positiva aplicada después de la canonicalisation.
- Proteja los endpoints de gestión con autenticación y segmentación de red.
Referencias
- CVE-2025-27636 – RCE in Apache Camel via header casing bypass (OffSec blog)
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers
- https://web.dev/security-headers/
- https://web.dev/articles/security-headers
tip
Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Hacking en Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.