En-têtes HTTP spéciaux
Reading time: 12 minutes
tip
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.
Listes de mots & Outils
- https://github.com/danielmiessler/SecLists/tree/master/Miscellaneous/Web/http-request-headers
- https://github.com/rfc-st/humble
En-têtes à modifier
Réécrire la source 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
(Vérifier les en-têtes hop-by-hop)
Réécrire l'emplacement :
X-Original-URL: /admin/console
X-Rewrite-URL: /admin/console
En-têtes hop-by-hop
Un en-tête hop-by-hop est un en-tête conçu pour être traité et consommé par le proxy qui gère actuellement la requête, contrairement à un en-tête end-to-end.
Connection: close, X-Forwarded-For
HTTP Request Smuggling
Content-Length: 30
Transfer-Encoding: chunked
HTTP Request Smuggling / HTTP Desync Attack
L'en-tête Expect
Il est possible que le client envoie l'en-tête Expect: 100-continue
et que le serveur réponde HTTP/1.1 100 Continue
pour permettre au client de continuer l'envoi du corps de la requête. Cependant, certains proxies n'aiment pas vraiment cet en-tête.
Résultats intéressants obtenus avec Expect: 100-continue
:
- Envoyer une requête HEAD avec un corps : le serveur n'a pas tenu compte que les requêtes HEAD n'ont pas de corps et garde la connexion ouverte jusqu'à expiration du timeout.
- D'autres serveurs ont renvoyé des données étranges : des données aléatoires lues depuis le socket dans la réponse, des clés secrètes, ou cela a même permis d'empêcher le front-end de supprimer certaines valeurs d'en-tête.
- Cela a aussi causé une désynchronisation
0.CL
car le backend a répondu avec un 400 au lieu de 100, mais le proxy front-end était prêt à envoyer le corps de la requête initiale ; il l'envoie donc et le backend l'interprète comme une nouvelle requête. - Envoyer une variation
Expect: y 100-continue
a aussi provoqué la désynchronisation0.CL
. - Une erreur similaire où le backend a répondu avec un 404 a généré une désynchronisation
CL.0
parce que la requête malveillante indiquait unContent-Length
. Le backend envoie donc la requête malveillante + les octets correspondant auContent-Length
de la requête suivante (d'une victim). Cela désynchronise la file : le backend envoie la réponse 404 pour la requête malveillante + la réponse de la requête de la victim, tandis que le front-end pensait qu'une seule requête avait été envoyée ; la seconde réponse est donc envoyée à une seconde requête victim et la réponse de celle-ci est envoyée à la suivante...
Pour plus d'infos sur HTTP Request Smuggling, consultez :
HTTP Request Smuggling / HTTP Desync Attack
En-têtes de cache
En-têtes de cache côté serveur :
X-Cache
dans la réponse peut valoirmiss
lorsque la requête n'a pas été mise en cache ethit
lorsqu'elle l'a été- Comportement similaire pour l'en-tête
Cf-Cache-Status
Cache-Control
indique si une ressource est mise en cache et quand elle expirera :Cache-Control: public, max-age=1800
Vary
est souvent utilisé dans la réponse pour indiquer des en-têtes supplémentaires qui sont traités comme faisant partie de la clé de cache même s'ils ne sont normalement pas pris en compte.Age
définit le temps en secondes pendant lequel l'objet est resté dans le cache du proxy.Server-Timing: cdn-cache; desc=HIT
indique aussi qu'une ressource a été mise en cache
Cache Poisoning and Cache Deception
En-têtes de cache local :
Clear-Site-Data
: en-tête indiquant le cache à supprimer :Clear-Site-Data: "cache", "cookies"
Expires
: contient la date/heure à laquelle la réponse expire :Expires: Wed, 21 Oct 2015 07:28:00 GMT
Pragma: no-cache
identique àCache-Control: no-cache
Warning
: l'en-tête HTTP génériqueWarning
contient des informations sur d'éventuels problèmes liés au statut du message. Plusieurs en-têtesWarning
peuvent apparaître dans une réponse.Warning: 110 anderson/1.3.37 "Response is stale"
Requêtes conditionnelles
- Les requêtes utilisant les en-têtes
If-Modified-Since
etIf-Unmodified-Since
recevront des données seulement si l'en-tête de réponseLast-Modified
contient une heure différente. - Les requêtes conditionnelles utilisant
If-Match
etIf-None-Match
se basent sur une valeur Etag : le serveur enverra le contenu si l'Etag a changé. L'Etag
provient de la réponse HTTP. - La valeur de l'Etag est généralement calculée à partir du contenu de la réponse. Par exemple,
ETag: W/"37-eL2g8DEyqntYlaLp5XLInBWsjWI"
indique que l'Etag
est le Sha1 de 37 octets.
Requêtes Range
Accept-Ranges
: Indique si le serveur supporte les requêtes de plage, et si oui dans quelle unité la plage peut être exprimée.Accept-Ranges: <range-unit>
Range
: Indique la partie d'un document que le serveur doit renvoyer. Par exemple,Range:80-100
renverra les octets 80 à 100 de la réponse originale avec un code 206 Partial Content. Pensez aussi à retirer l'en-têteAccept-Encoding
de la requête.- Cela peut être utile pour obtenir une réponse contenant du code javascript réfléchi arbitraire qui serait autrement échappé. Mais pour abuser de cela, il faut pouvoir injecter ces en-têtes dans la requête.
If-Range
: Crée une requête de plage conditionnelle qui n'est satisfaite que si l'etag ou la date fournie correspond à la ressource distante. Utilisé pour éviter de télécharger deux plages de versions incompatibles de la ressource.Content-Range
: Indique où, dans un corps complet, un message partiel appartient.
Informations sur le corps du message
Content-Length
: La taille de la ressource, en nombre décimal d'octets.Content-Type
: Indique le type media de la ressourceContent-Encoding
: Utilisé pour spécifier l'algorithme de compression.Content-Language
: Décrit la ou les langues humaines destinées au public, permettant à un utilisateur de différencier selon ses préférences linguistiques.Content-Location
: Indique un emplacement alternatif pour les données retournées.
D'un point de vue pentest, ces informations sont généralement « inutiles », mais si la ressource est protégée par un 401 ou 403 et que vous trouvez un moyen d'obtenir ces info, cela peut être intéressant.
Par exemple, une combinaison de Range
et Etag
dans une requête HEAD peut leak le contenu de la page via des requêtes HEAD :
- Une requête avec l'en-tête
Range: bytes=20-20
et une réponse contenantETag: W/"1-eoGvPlkaxxP4HqHv6T3PNhV9g3Y"
leak que le SHA1 de l'octet 20 estETag: eoGvPlkaxxP4HqHv6T3PNhV9g3Y
Infos serveur
Server: Apache/2.4.1 (Unix)
X-Powered-By: PHP/5.3.3
Contrôles
Allow
: Cet en-tête sert à communiquer les méthodes HTTP qu'une ressource peut gérer. Par exemple :Allow: GET, POST, HEAD
indique que la ressource supporte ces méthodes.Expect
: Utilisé par le client pour exprimer des attentes que le serveur doit satisfaire pour que la requête soit traitée avec succès. Un cas courant estExpect: 100-continue
, qui signale que le client a l'intention d'envoyer une grande charge de données et attend une réponse100 (Continue)
avant de procéder. Ce mécanisme aide à optimiser l'utilisation du réseau en attendant la confirmation du serveur.
Téléchargements
- L'en-tête
Content-Disposition
dans les réponses HTTP indique si un fichier doit être affiché inline (dans la page web) ou traité comme une attachment (téléchargé). Par exemple:
Content-Disposition: attachment; filename="filename.jpg"
Cela signifie que le fichier nommé "filename.jpg" est destiné à être téléchargé et enregistré.
En-têtes de sécurité
Politique de sécurité du contenu (CSP)
Content Security Policy (CSP) Bypass
Trusted Types
En appliquant Trusted Types via CSP, les applications peuvent être protégées contre les attaques DOM XSS. Trusted Types veillent à ce que seuls des objets spécifiquement conçus, conformes aux politiques de sécurité établies, puissent être utilisés dans des appels d'API web dangereux, sécurisant ainsi le code JavaScript par défaut.
// 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
Cet en-tête empêche le sniffing des types MIME, une pratique qui pourrait conduire à des vulnérabilités XSS. Il garantit que les navigateurs respectent les types MIME spécifiés par le serveur.
X-Content-Type-Options: nosniff
X-Frame-Options
Pour lutter contre le clickjacking, cet en-tête restreint la manière dont les documents peuvent être intégrés dans les balises <frame>
, <iframe>
, <embed>
ou <object>
, en recommandant que tous les documents spécifient explicitement leurs permissions d'intégration.
X-Frame-Options: DENY
Cross-Origin Resource Policy (CORP) and Cross-Origin Resource Sharing (CORS)
CORP est crucial pour spécifier quelles ressources peuvent être chargées par les sites web, atténuant les cross-site leaks. CORS, en revanche, permet un mécanisme de cross-origin resource sharing plus flexible, assouplissant la same-origin policy sous certaines conditions.
Cross-Origin-Resource-Policy: same-origin
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true
Politique d'intégration inter-origines (COEP) et Politique d'ouverture inter-origines (COOP)
COEP et COOP sont essentielles pour permettre l'isolation inter-origines, réduisant significativement le risque d'attaques de type Spectre. Elles contrôlent respectivement le chargement des ressources provenant d'autres origines et l'interaction avec les fenêtres provenant d'autres origines.
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin-allow-popups
HTTP Strict Transport Security (HSTS)
Enfin, HSTS est une fonctionnalité de sécurité qui oblige les navigateurs à communiquer avec les serveurs uniquement via des connexions HTTPS sécurisées, améliorant ainsi la confidentialité et la sécurité.
Strict-Transport-Security: max-age=3153600
Contournement de la casse des noms d'en-tête
HTTP/1.1 définit les noms de champs d'en-tête comme insensibles à la casse (RFC 9110 §5.1). Néanmoins, il est très courant de trouver des middlewares personnalisés, des filtres de sécurité ou de la logique métier qui comparent le nom d'en-tête littéral reçu sans normaliser la casse au préalable (par ex. header.equals("CamelExecCommandExecutable")
). Si ces vérifications sont effectuées de manière sensible à la casse, un attaquant peut les contourner simplement en envoyant le même en-tête avec une capitalisation différente.
Typical situations where this mistake appears:
- Listes allow/deny personnalisées qui tentent de bloquer des en-têtes internes “dangereux” avant que la requête n'atteigne un composant sensible.
- Implémentations internes de pseudo-en-têtes de reverse-proxy (par ex.
X-Forwarded-For
sanitisation). - Frameworks qui exposent des endpoints de management / debug et se reposent sur les noms d'en-tête pour l'authentification ou la sélection de commandes.
Exploiter le contournement
- Identifiez un en-tête qui est filtré ou validé côté serveur (par exemple, en lisant le code source, la documentation, ou les messages d'erreur).
- Envoyez le même en-tête avec une casse différente (mixte ou majuscules). Parce que les stacks HTTP canonisent généralement les en-têtes seulement après l'exécution du code utilisateur, la vérification vulnérable peut être ignorée.
- Si le composant en aval traite les en-têtes de façon insensible à la casse (la plupart le font), il acceptera la valeur contrôlée par l'attaquant.
Exemple : Apache Camel exec
RCE (CVE-2025-27636)
Dans les versions vulnérables d'Apache Camel, les routes du Command Center tentent de bloquer les requêtes non fiables en supprimant les en-têtes CamelExecCommandExecutable
et CamelExecCommandArgs
. La comparaison était effectuée avec equals()
, donc seuls les noms avec la casse exacte étaient supprimés.
# 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: /"
Les en-têtes atteignent le composant exec
sans filtrage, entraînant une exécution de commandes à distance avec les privilèges du processus Camel.
Détection & atténuation
- Normalisez tous les noms d'en-tête sur une même casse (généralement en minuscules) avant d'effectuer les comparaisons allow/deny.
- Rejetez les doublons suspects : si
Header:
etHeAdEr:
sont présents simultanément, considérez-le comme une anomalie. - Utilisez une allow-list positive appliquée après la canonicalisation.
- Protégez les endpoints de gestion avec de l'authentification et une segmentation réseau.
Références
- 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
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.