# En-têtes HTTP spéciaux {{#include ../../banners/hacktricks-training.md}} ## Listes de mots & Outils - [https://github.com/danielmiessler/SecLists/tree/master/Miscellaneous/Web/http-request-headers](https://github.com/danielmiessler/SecLists/tree/master/Miscellaneous/Web/http-request-headers) - [https://github.com/rfc-st/humble](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` {{#ref}} ../../pentesting-web/abusing-hop-by-hop-headers.md {{#endref}} ## HTTP Request Smuggling - `Content-Length: 30` - `Transfer-Encoding: chunked` {{#ref}} ../../pentesting-web/http-request-smuggling/ {{#endref}} ## 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ésynchronisation `0.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 un `Content-Length`. Le backend envoie donc la requête malveillante + les octets correspondant au `Content-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 : {{#ref}} ../../pentesting-web/http-request-smuggling/ {{#endref}} ## En-têtes de cache **En-têtes de cache côté serveur** : - **`X-Cache`** dans la réponse peut valoir **`miss`** lorsque la requête n'a pas été mise en cache et **`hit`** 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 {{#ref}} ../../pentesting-web/cache-deception/ {{#endref}} **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érique `Warning` contient des informations sur d'éventuels problèmes liés au statut du message. Plusieurs en-têtes `Warning` 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`** et **`If-Unmodified-Since`** recevront des données seulement si l'en-tête de réponse **`Last-Modified`** contient une heure différente. - Les requêtes conditionnelles utilisant **`If-Match`** et **`If-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`** : 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ête `Accept-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 ressource - **`Content-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 contenant `ETag: W/"1-eoGvPlkaxxP4HqHv6T3PNhV9g3Y"` leak que le SHA1 de l'octet 20 est `ETag: 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 est `Expect: 100-continue`, qui signale que le client a l'intention d'envoyer une grande charge de données et attend une réponse `100 (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) {{#ref}} ../../pentesting-web/content-security-policy-csp-bypass/ {{#endref}} ### **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. ```javascript // Feature detection if (window.trustedTypes && trustedTypes.createPolicy) { // Name and create a policy const policy = trustedTypes.createPolicy('escapePolicy', { createHTML: str => str.replace(/\/g, '>'); }); } ``` ```javascript // Assignment of raw strings is blocked, ensuring safety. el.innerHTML = "some string" // Throws an exception. const escaped = policy.createHTML("") 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 ``, `