Special HTTP headers
Reading time: 12 minutes
tip
Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporte o HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do 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
Rewrite IP source:
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
(Check hop-by-hop headers)
Rewrite location:
X-Original-URL: /admin/console
X-Rewrite-URL: /admin/console
Hop-by-Hop headers
A hop-by-hop header is a header which is designed to be processed and consumed by the proxy currently handling the request, as opposed to an end-to-end header.
Connection: close, X-Forwarded-For
HTTP Request Smuggling
Content-Length: 30
Transfer-Encoding: chunked
HTTP Request Smuggling / HTTP Desync Attack
The Expect header
It's posible for the client to send the header Expect: 100-continue
and then the server could respond with HTTP/1.1 100 Continue
to allow the client to continue sending the body of the request. However, some proxies don't really llike this header.
Interesting results of Expect: 100-continue
:
- Sending a HEAD request with a body the server didn't took into account that HEAD requests don't have body and keep the connection open until it timed out.
- Another servers sent extrange data: Random data read from the socket in the response, secret keys or even it allowed to prevent the front-end from removing header values.
- It also caused a
0.CL
desync cause the backend responded with a 400 response isntead of a 100 response, but the proxy front-end was prepared to send the body of the initial request, so it sends it and the backend takes it as new request. - Sending an
Expect: y 100-continue
variation also caused the0.CL
desync. - A similar error where the backend responded with a 404 generated a
CL.0
desync because the malicious request indicates aContent-Length
so the backend sends the malicious request + theContent-Length
bytes of the next request (of a victim), this desyncs the queue cause the backend sends the 404 request for the malicious request + the repsonse of the victim requests, but the front end thought that only 1 request was sent, so the second response is sent to a seond victim request and the the reponse of taht one is sent to the next one...
For more info about HTTP Request Smuggling check:
HTTP Request Smuggling / HTTP Desync Attack
Cache Headers
Server Cache Headers:
X-Cache
in the response may have the valuemiss
when the request wasn't cached and the valuehit
when it is cached- Similar behaviour in the header
Cf-Cache-Status
Cache-Control
indicates if a resource is being cached and when will be the next time the resource will be cached again:Cache-Control: public, max-age=1800
Vary
is often used in the response to indicate additional headers that are treated as part of the cache key even if they are normally unkeyed.Age
defines the times in seconds the object has been in the proxy cache.Server-Timing: cdn-cache; desc=HIT
also indicates that a resource was cached
Cache Poisoning and Cache Deception
Local Cache headers:
Clear-Site-Data
: Header to indicate the cache that should be removed:Clear-Site-Data: "cache", "cookies"
Expires
: Contains date/time when the response should expire:Expires: Wed, 21 Oct 2015 07:28:00 GMT
Pragma: no-cache
same asCache-Control: no-cache
Warning
: TheWarning
general HTTP header contains information about possible problems with the status of the message. More than oneWarning
header may appear in a response.Warning: 110 anderson/1.3.37 "Response is stale"
Conditionals
- Requests using these headers:
If-Modified-Since
andIf-Unmodified-Since
will be responded with data only if the response header**Last-Modified
** contains a different time. - Conditional requests using
If-Match
andIf-None-Match
use an Etag value so the web server will send the content of the response if the data (Etag) has changed. TheEtag
is taken from the HTTP response. - The Etag value is usually calculated based on the content of the response. For example,
ETag: W/"37-eL2g8DEyqntYlaLp5XLInBWsjWI"
indicates that theEtag
is the Sha1 of 37 bytes.
Range requests
Accept-Ranges
: Indicates if the server supports range requests, and if so in which unit the range can be expressed.Accept-Ranges: <range-unit>
Range
: Indicates the part of a document that the server should return. For emxaple,Range:80-100
will return the bytes 80 to 100 of the original response with a status code of 206 Partial Content. Also remember to remove theAccept-Encoding
header from the request.- This could be useful to get a repsonse with arbitrary reflected javascript code that otherwise could be escaped. But to abuse this you would need to inject this headers in the request.
If-Range
: Creates a conditional range request that is only fulfilled if the given etag or date matches the remote resource. Used to prevent downloading two ranges from incompatible version of the resource.Content-Range
: Indicates where in a full body message a partial message belongs.
Message body information
Content-Length
: The size of the resource, in decimal number of bytes.Content-Type
: Indicates the media type of the resourceContent-Encoding
: Used to specify the compression algorithm.Content-Language
: Describes the human language(s) intended for the audience, so that it allows a user to differentiate according to the users' own preferred language.Content-Location
: Indicates an alternate location for the returned data.
From a pentest point of view this information is usually "useless", but if the resource is protected by a 401 or 403 and you can find some way to get this info, this could be interesting.
For example a combination of Range
and Etag
in a HEAD request can leak the content of the page via HEAD requests:
- A request with the header
Range: bytes=20-20
and with a response containingETag: W/"1-eoGvPlkaxxP4HqHv6T3PNhV9g3Y"
is leaking that the SHA1 of the byte 20 isETag: eoGvPlkaxxP4HqHv6T3PNhV9g3Y
Server Info
Server: Apache/2.4.1 (Unix)
X-Powered-By: PHP/5.3.3
Controls
Allow
: This header is used to communicate the HTTP methods a resource can handle. For example, it might be specified asAllow: GET, POST, HEAD
, indicating that the resource supports these methods.Expect
: Utilized by the client to convey expectations that the server needs to meet for the request to be processed successfully. A common use case involves theExpect: 100-continue
header, which signals that the client intends to send a large data payload. The client looks for a100 (Continue)
response before proceeding with the transmission. This mechanism helps in optimizing network usage by awaiting server confirmation.
Downloads
- The
Content-Disposition
header in HTTP responses directs whether a file should be displayed inline (within the webpage) or treated as an attachment (downloaded). For instance:
Content-Disposition: attachment; filename="filename.jpg"
Isso significa que o arquivo chamado "filename.jpg" destina-se a ser baixado e salvo.
Cabeçalhos de Segurança
Content Security Policy (CSP)
Content Security Policy (CSP) Bypass
Trusted Types
Ao aplicar Trusted Types via CSP, as aplicações podem ser protegidas contra ataques DOM XSS. Trusted Types garantem que apenas objetos especificamente criados, em conformidade com as políticas de segurança estabelecidas, possam ser usados em chamadas de APIs web perigosas, protegendo assim o código JavaScript por padrão.
// 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 cabeçalho evita a inspeção de tipo MIME, uma prática que pode levar a vulnerabilidades XSS. Ele assegura que os navegadores respeitem os tipos MIME especificados pelo servidor.
X-Content-Type-Options: nosniff
X-Frame-Options
Para combater o clickjacking, este cabeçalho restringe como documentos podem ser incorporados em <frame>
, <iframe>
, <embed>
ou <object>
, recomendando que todos os documentos especifiquem explicitamente suas permissões de incorporação.
X-Frame-Options: DENY
Cross-Origin Resource Policy (CORP) e Cross-Origin Resource Sharing (CORS)
CORP é crucial para especificar quais recursos podem ser carregados por websites, mitigando cross-site leaks. CORS, por outro lado, permite um mecanismo mais flexível de cross-origin resource sharing, relaxando a same-origin policy sob certas condições.
Cross-Origin-Resource-Policy: same-origin
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true
Cross-Origin Embedder Policy (COEP) e Cross-Origin Opener Policy (COOP)
COEP e COOP são essenciais para habilitar o isolamento cross-origin, reduzindo significativamente o risco de ataques semelhantes ao Spectre. Elas controlam, respectivamente, o carregamento de recursos cross-origin e a interação com janelas cross-origin.
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin-allow-popups
HTTP Strict Transport Security (HSTS)
Por fim, HSTS é um recurso de segurança que obriga os navegadores a se comunicarem com os servidores apenas por meio de conexões HTTPS seguras, melhorando assim a privacidade e a segurança.
Strict-Transport-Security: max-age=3153600
Header Name Casing Bypass
HTTP/1.1 define os nomes de campos de header como insensíveis a maiúsculas/minúsculas (RFC 9110 §5.1). No entanto, é muito comum encontrar middleware personalizado, filtros de segurança ou lógica de negócio que comparam o nome literal do header recebido sem normalizar a capitalização primeiro (por exemplo, header.equals("CamelExecCommandExecutable")
). Se essas verificações forem feitas sensíveis a maiúsculas/minúsculas, um atacante pode contorná-las simplesmente enviando o mesmo header com uma capitalização diferente.
Typical situations where this mistake appears:
- Listas personalizadas de allow/deny que tentam bloquear headers internos “perigosos” antes que a requisição alcance um componente sensível.
- Implementações internas de pseudo-headers de reverse-proxy (por exemplo,
X-Forwarded-For
sanitização). - Frameworks que expõem endpoints de management / debug e dependem dos nomes de header para autenticação ou seleção de comandos.
Abusando do bypass
- Identifique um header que seja filtrado ou validado no lado do servidor (por exemplo, lendo o código-fonte, documentação ou mensagens de erro).
- Envie o mesmo header com uma capitalização diferente (caixa mista ou apenas maiúsculas). Como as pilhas HTTP normalmente normalizam os headers apenas após o código do usuário ser executado, a verificação vulnerável pode ser ignorada.
- Se o componente downstream tratar headers de forma insensível a maiúsculas/minúsculas (a maioria trata), ele aceitará o valor controlado pelo atacante.
Example: Apache Camel exec
RCE (CVE-2025-27636)
Em versões vulneráveis do Apache Camel as rotas do Command Center tentavam bloquear requisições não confiáveis removendo os headers CamelExecCommandExecutable
e CamelExecCommandArgs
. A comparação era feita com equals()
, então apenas os nomes exatamente em minúsculas eram removidos.
# 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: /"
Os cabeçalhos chegam ao componente exec
sem filtragem, resultando em execução remota de comandos com os privilégios do processo Camel.
Detecção e Mitigação
- Normalizar todos os nomes de cabeçalho para um único case (normalmente minúsculas) antes de realizar comparações allow/deny.
- Rejeitar duplicatas suspeitas: se tanto
Header:
quantoHeAdEr:
estiverem presentes, tratar como uma anomalia. - Usar uma allow-list positiva aplicada após a canonicalização.
- Proteger management endpoints com autenticação e segmentação de rede.
Referências
- 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
Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporte o HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.