Cabeceras HTTP especiales
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
Encabezados para cambiar ubicación
Reescribir IP de origen:
X-Originating-IP: 127.0.0.1X-Forwarded-For: 127.0.0.1X-Forwarded: 127.0.0.1Forwarded-For: 127.0.0.1X-Forwarded-Host: 127.0.0.1X-Remote-IP: 127.0.0.1X-Remote-Addr: 127.0.0.1X-ProxyUser-Ip: 127.0.0.1X-Original-URL: 127.0.0.1Client-IP: 127.0.0.1X-Client-IP: 127.0.0.1X-Host: 127.0.0.1True-Client-IP: 127.0.0.1Cluster-Client-IP: 127.0.0.1Via: 1.0 fred, 1.1 127.0.0.1Connection: close, X-Forwarded-For(Revisar hop-by-hop headers)
Reescribir ubicación:
X-Original-URL: /admin/consoleX-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 maneja actualmente la petición, a diferencia de una cabecera end-to-end.
Connection: close, X-Forwarded-For
HTTP Request Smuggling
Content-Length: 30Transfer-Encoding: chunked
HTTP Request Smuggling / HTTP Desync Attack
El encabezado Expect
Es posible que el cliente envíe la cabecera Expect: 100-continue y que 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, algunos proxies no manejan bien esta cabecera.
Resultados interesantes de Expect: 100-continue:
- Enviar una petición HEAD con body: el servidor no tuvo en cuenta que las peticiones HEAD no deberían tener body y mantiene la conexión abierta hasta que expira el timeout.
- Algunos servidores respondieron con datos extraños: datos aleatorios leídos del socket en la respuesta, claves secretas o incluso permitió evitar que el front-end eliminara valores de cabeceras.
- También causó un desync
0.CLporque 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-continuetambién causó el desync0.CL. - Un error similar donde el backend respondió con un 404 generó un desync
CL.0porque la petición maliciosa indicaba unContent-Length, por lo que el backend envía la petición maliciosa + los bytes delContent-Lengthde 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 la petición de la víctima, pero el front-end pensó que solo se envió 1 petición, así que la segunda respuesta se envía a una segunda víctima y la respuesta de esa va a la siguiente…
Para más info sobre HTTP Request Smuggling consulta:
HTTP Request Smuggling / HTTP Desync Attack
Encabezados de caché
Server Cache Headers:
X-Cacheen la respuesta puede tener el valormisscuando la petición no estuvo en caché y el valorhitcuando está cacheada.- Comportamiento similar en la cabecera
Cf-Cache-Status. Cache-Controlindica si un recurso está siendo cacheado y cuándo volverá a estarlo:Cache-Control: public, max-age=1800Varyse usa a menudo en la respuesta para indicar cabeceras adicionales que se tratan como parte de la clave de caché incluso si normalmente no se consideran.Agedefine el tiempo en segundos que el objeto ha estado en la caché del proxy.Server-Timing: cdn-cache; desc=HITtambién indica que un recurso fue cacheado.
Cache Poisoning and Cache Deception
Local Cache headers:
Clear-Site-Data: Cabecera para indicar la caché que debe eliminarse:Clear-Site-Data: "cache", "cookies"Expires: Contiene la fecha/hora cuando la respuesta debe expirar:Expires: Wed, 21 Oct 2015 07:28:00 GMTPragma: no-cacheigual queCache-Control: no-cacheWarning: La cabecera general HTTPWarningcontiene información sobre posibles problemas con el estado del mensaje. Puede aparecer más de una cabeceraWarningen una respuesta.Warning: 110 anderson/1.3.37 "Response is stale"
Condicionales
- Las peticiones que usan las cabeceras
If-Modified-SinceyIf-Unmodified-Sinceserán respondidas con datos solo si la cabecera de respuestaLast-Modifiedcontiene una hora diferente. - Las peticiones condicionales usando
If-MatchyIf-None-Matchusan un valor ETag para que el servidor solo envíe el contenido si el dato (Etag) ha cambiado. ElEtagse 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 elEtages el sha1 de 37 bytes.
Solicitudes de rango
Accept-Ranges: Indica si el servidor soporta range requests, y si es así en qué unidad se puede expresar el rango.Accept-Ranges: <range-unit>Range: Indica la parte de un documento que el servidor debe devolver. Por ejemplo,Range:80-100devolverá los bytes 80 a 100 de la respuesta original con un código 206 Partial Content. También recuerda eliminar la cabeceraAccept-Encodingde 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 satisface si el etag o la fecha dada coincide con el recurso remoto. Se usa para evitar descargar dos ranges de versiones incompatibles del recurso.Content-Range: Indica dónde pertenece un mensaje parcial dentro de un body completo.
Información del body del mensaje
Content-Length: El tamaño del recurso, en número decimal de bytes.Content-Type: Indica el media type del recurso.Content-Encoding: Usado para especificar el algoritmo de compresión.Content-Language: Describe el(los) idioma(s) humano(s) al que va dirigido, para que el usuario pueda diferenciar según sus preferencias.Content-Location: Indica una ubicación alternativa para los datos devueltos.
Desde un punto de vista de pentest esta información suele ser “inútil”, pero si el recurso está protegido por un 401 o 403 y puedes encontrar alguna forma 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 the content of the page via HEAD requests:
- Una petición con la cabecera
Range: bytes=20-20y con una respuesta que contieneETag: W/"1-eoGvPlkaxxP4HqHv6T3PNhV9g3Y"está leaking 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 aparecer 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 se procese correctamente. Un caso de uso común es la cabeceraExpect: 100-continue, que indica que el cliente planea enviar una gran carga de datos. El cliente espera una respuesta100 (Continue)antes de proceder con la transmisión. Este mecanismo ayuda a optimizar el uso de la red al esperar la confirmación del servidor.
Descargas
- La cabecera
Content-Dispositionen las respuestas HTTP indica si un archivo debe mostrarse inline (dentro de la página) 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
Política de Seguridad de Contenido (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 usarse 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 el sniffing de tipos MIME, una práctica que podría llevar a vulnerabilidades XSS. Asegura que los navegadores respeten los tipos MIME especificados por el servidor.
X-Content-Type-Options: nosniff
X-Frame-Options
Para combatir el clickjacking, esta cabecera restringe cómo se pueden incrustar los documentos en las etiquetas <frame>, <iframe>, <embed> o <object>, recomendando que todos los documentos especifiquen explícitamente sus permisos de inclusión.
X-Frame-Options: DENY
Cross-Origin Resource Policy (CORP) and Cross-Origin Resource Sharing (CORS)
CORP es crucial para especificar qué recursos pueden ser cargados por los sitios web, mitigando los 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 tipo Spectre. Controlan, respectivamente, la carga de recursos entre orígenes y la interacción con ventanas entre orígenes.
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
Permissions-Policy (formerly Feature-Policy)
Permissions-Policy permite a los desarrolladores web habilitar, deshabilitar o modificar selectivamente el comportamiento de ciertas características del navegador y APIs dentro de un documento. Es el sucesor del encabezado Feature-Policy, ahora obsoleto. Este encabezado ayuda a reducir la superficie de ataque al restringir el acceso a funciones potentes que podrían ser abusadas.
Permissions-Policy: geolocation=(), camera=(), microphone=()
Directivas comunes:
| Directive | Descripción |
|---|---|
accelerometer | Controla el acceso al sensor de acelerómetro |
camera | Controla el acceso a dispositivos de entrada de vídeo (cámara web) |
geolocation | Controla el acceso a la API de Geolocation |
gyroscope | Controla el acceso al sensor de giroscopio |
magnetometer | Controla el acceso al sensor de magnetómetro |
microphone | Controla el acceso a dispositivos de entrada de audio |
payment | Controla el acceso a la Payment Request API |
usb | Controla el acceso a la WebUSB API |
fullscreen | Controla el acceso a la Fullscreen API |
autoplay | Controla si los medios pueden reproducirse automáticamente |
clipboard-read | Controla el acceso para leer el contenido del portapapeles |
clipboard-write | Controla el acceso para escribir en el portapapeles |
Valores de sintaxis:
()- Desactiva la característica por completo(self)- Permite la característica solo para el mismo origen*- Permite la característica para todos los orígenes(self "https://example.com")- Permite para el mismo origen y el dominio especificado
Configuraciones de ejemplo:
# Restrictive policy - disable most features
Permissions-Policy: geolocation=(), camera=(), microphone=(), payment=(), usb=()
# Allow camera only from same origin
Permissions-Policy: camera=(self)
# Allow geolocation for same origin and a trusted partner
Permissions-Policy: geolocation=(self "https://maps.example.com")
Desde una perspectiva de seguridad, la ausencia o una configuración demasiado permisiva de la cabecera Permissions-Policy puede permitir a atacantes (por ejemplo, mediante XSS o iframes embebidos) abusar de funciones potentes del navegador. Restringe siempre las funciones al mínimo necesario para tu aplicación.
Bypass por mayúsculas/minúsculas en nombres de cabecera
HTTP/1.1 define los nombres de campo 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 literal de la cabecera recibida sin normalizar primero el uso de mayúsculas/minúsculas (p. ej., header.equals("CamelExecCommandExecutable")). Si esas comprobaciones se realizan de forma sensible a mayúsculas/minúsculas, un atacante puede eludirlas simplemente enviando la misma cabecera con una capitalización diferente.
Situaciones típicas en las que aparece este error:
- Listas personalizadas de allow/deny que intentan bloquear cabeceras internas “peligrosas” antes de que la petición alcance un componente sensible.
- Implementaciones internas de pseudo-cabeceras de reverse-proxy (p. ej., saneamiento de
X-Forwarded-For). - Frameworks que exponen endpoints de gestión/depuración y que confían en los nombres de cabecera para autenticación o selección de comandos.
Explotación del bypass
- Identifica una cabecera que sea filtrada o validada en el servidor (por ejemplo, leyendo código fuente, documentación o mensajes de error).
- Envía la misma cabecera con una capitalización diferente (con mezcla de mayúsculas/minúsculas o todo en mayúsculas). Debido a que las pilas HTTP suelen canonizar las cabeceras solo después de que se ejecute el código del usuario, la comprobación vulnerable puede ser evitada.
- Si el componente aguas abajo trata las cabeceras de forma insensible a mayúsculas/minúsculas (la mayoría lo hace), aceptará el valor controlado por el atacante.
Ejemplo: Apache Camel exec RCE (CVE-2025-27636)
En versiones vulnerables de Apache Camel, las rutas Command Center intentan bloquear solicitudes no confiables eliminando las cabeceras CamelExecCommandExecutable y CamelExecCommandArgs. La comparación se hacía con equals(), por lo que solo se eliminaban los nombres exactamente en minúsculas.
# 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: /"
Los encabezados llegan al componente exec sin filtrarse, resultando en ejecución remota de comandos con los privilegios del proceso Camel.
Detección & Mitigación
- Normalizar todos los nombres de encabezado a un único caso (usualmente lowercase) antes de realizar comparaciones allow/deny.
- Rechazar duplicados sospechosos: si tanto
Header:comoHeAdEr:están presentes, considerarlo una anomalía. - Usar una allow-list positiva aplicada después de la canonicalisation.
- Proteger 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.


