Quand le Parsing de Protocole Fuite dans la Logique Applicative

root@thebughunter:~$ cat injection_en_tete.txt
Cible : Instance GitLab
Vulnérabilité : Injection CRLF → Empoisonnement du Host Header
Impact : Redirection Ouverte au Niveau Applicatif
Statut : Confirmé et Corrigé
La Version Courte
J'ai trouvé un moyen d'injecter des en-têtes arbitraires dans les requêtes HTTP en abusant de la façon dont le serveur interprétait les séquences CRLF encodées en URL. Cela m'a permis d'écraser l'en-tête Host et de tromper l'application pour qu'elle redirige les utilisateurs vers un domaine contrôlé par l'attaquant.
Ça semble compliqué ? Laissez-moi vous expliquer.
C'est Quoi au Juste l'Injection CRLF ?
CRLF signifie Carriage Return (\r) et Line Feed (\n). En HTTP, ces caractères séparent les en-têtes les uns des autres et du corps de la requête. Quand un serveur ne nettoie pas correctement ces caractères dans les entrées utilisateur, vous pouvez injecter vos propres en-têtes dans la réponse.
Les versions encodées en URL sont :
%0d= Retour chariot (\r)%0a= Saut de ligne (\n)
Si un serveur les décode et les traite comme de vrais retours à la ligne, vous avez un problème.
Trouver le Point d'Injection
Je fouillais une instance GitLab quand j'ai décidé de tester l'injection CRLF dans le chemin URL. Mon premier test était assez simple — injecter une version HTTP invalide et un en-tête bidon pour voir si le serveur allait flancher.
https://gitlab.target.com/%20HTTP/9%0D%0ATransfer-Encoding:%20nonexistent%0D%0Ax-end:%20a
Décomposition :
%20- Caractère espaceHTTP/9- Une version HTTP inexistante%0D%0A- Séquence CRLFTransfer-Encoding: nonexistent- En-tête invalide- Un autre CRLF et un en-tête factice pour fermer le tout
Le serveur a répondu avec une erreur 505 HTTP Version Not Supported.
POURQUOI C'EST IMPORTANT
Une réponse 505 pour HTTP/9 signifie que le serveur a effectivement interprété ma version de protocole injectée. Il n'a pas juste traité toute mon entrée comme un chemin URL — il a interprété les séquences CRLF et essayé de traiter ce qui suivait comme des en-têtes HTTP.
Cela confirmait que le serveur était vulnérable à l'injection CRLF. Maintenant la question était : qu'est-ce que je peux réellement faire avec ça ?
Escalade vers l'Empoisonnement du Host Header
C'est là que ça devient intéressant. Si je peux injecter des en-têtes, puis-je injecter un nouvel en-tête Host ?
https://gitlab.target.com/%20HTTP/1.1%0d%0aHost:%20attacker.com%0d%0a%0d%0a
Ce que je fais ici :
- Injection d'une version HTTP valide (
HTTP/1.1) - Ajout d'un CRLF
- Injection de mon propre en-tête
Host: attacker.com - Double CRLF pour terminer la section des en-têtes
Et ça a marché. La réponse du serveur contenait :
HTTP/1.1 302 Found
Location: https://attacker.com/users/sign_in
L'application a pris mon en-tête Host injecté et l'a utilisé pour construire l'URL de redirection. Elle a même ajouté son chemin de connexion par défaut (/users/sign_in) à mon domaine.
Pourquoi C'est Grave
CE QU'UN ATTAQUANT PEUT FAIRE
POURQUOI C'EST SOURNOIS
Mettez-vous à la place d'une victime. Elle reçoit un lien qui commence par https://gitlab.target.com/... — ça a l'air légitime, non ? Elle clique dessus, et soudainement elle se retrouve sur attacker.com/users/sign_in face à ce qui ressemble à une page de connexion GitLab.
La Cause Racine
Cette vulnérabilité existe à cause d'un décalage entre la façon dont les différentes couches traitent l'entrée :
- Le serveur web décode les caractères encodés en URL dans le chemin
- Le parseur HTTP interprète les séquences CRLF comme des séparateurs d'en-têtes
- L'application fait confiance au Host header pour construire les URLs
Chaque couche fait correctement son travail de manière isolée. Le problème est que personne ne s'attendait à ce que les séquences CRLF encodées en URL dans le chemin survivent assez longtemps pour affecter l'analyse des en-têtes.
POINT CLÉ
Le parsing de protocole (HTTP) et la logique applicative (routage URL, redirections) doivent être complètement isolés. Quand ils ne le sont pas, des trucs bizarres comme ça arrivent.
Comment Tester Ça
Si vous voulez chercher des vulnérabilités similaires :
Étape 1 : Tester l'interprétation CRLF
Essayez d'injecter une version HTTP invalide :
https://target.com/%20HTTP/9%0D%0AX-Test:%20injected
Si vous obtenez un 505 ou une erreur de protocole similaire, le serveur interprète vos séquences CRLF.
Étape 2 : Essayer d'injecter différents en-têtes
https://target.com/%20HTTP/1.1%0d%0aHost:%20your-server.com%0d%0a%0d%0a
Vérifiez si des redirections ou des liens dans la réponse utilisent votre host injecté.
Étape 3 : Vérifier le potentiel d'empoisonnement de cache
Si la réponse est mise en cache avec votre Host header empoisonné, vous pourriez avoir une vulnérabilité d'empoisonnement de cache en plus. C'est tout un autre sujet.
Atténuation
Pour les développeurs confrontés à ce problème :
- Rejeter les CRLF dans les chemins URL - N'autorisez pas
%0dou%0adans les chemins URL, point final - Valider les Host headers - Comparez avec une liste blanche de hosts attendus
- Utiliser les URLs absolues avec précaution - Ne faites pas aveuglément confiance au Host header pour construire les URLs de redirection
- Défense en profondeur - Appliquez des protections à plusieurs niveaux (reverse proxy, serveur web, application)
Quoi d'Autre Pourrait en Découler ?
Je me suis concentré sur la redirection ouverte parce que c'était l'impact le plus clair que je pouvais démontrer. Mais l'injection CRLF ouvre la porte à bien plus si on creuse davantage.
Response Splitting / XSS
Si le point d'injection se reflète dans les en-têtes de réponse, vous pouvez potentiellement injecter un double CRLF et commencer à écrire votre propre corps de réponse. Ça veut dire du HTML arbitraire, donc du XSS.
%0d%0a%0d%0a<script>alert(document.domain)</script>
J'ai testé ça mais le serveur ne reflétait pas mon entrée dans la réponse d'une manière qui rendait ça exploitable. Ça vaut quand même le coup d'essayer.
Fixation de Session
Si vous pouvez injecter des en-têtes, vous pourriez pouvoir injecter des en-têtes Set-Cookie :
%0d%0aSet-Cookie:%20session=valeur-controlee-par-attaquant
Forcez une victime à utiliser un identifiant de session que vous contrôlez, puis détournez sa session après qu'elle se soit authentifiée.
Empoisonnement de Cache
Si la réponse est mise en cache (par un CDN, un reverse proxy ou un navigateur), vous pourriez empoisonner le cache avec votre redirection malveillante ou votre contenu injecté. Chaque utilisateur suivant qui accède à cette réponse en cache serait attaqué.
Contournement des En-têtes de Sécurité
Certaines applications comptent sur des en-têtes comme X-Frame-Options ou Content-Security-Policy pour leur protection. Si vous pouvez injecter des en-têtes, vous pourriez écraser ou neutraliser ces protections en injectant vos propres versions plus tôt dans la réponse.
Request Smuggling
Dans certaines configurations, l'injection CRLF dans la requête peut mener au HTTP request smuggling. Vous créez essentiellement une ambiguïté sur l'endroit où une requête se termine et une autre commence. Ça se complique vite, mais le gain peut être énorme — contournement des contrôles de sécurité, accès aux réponses d'autres utilisateurs, empoisonnement de cache à grande échelle.
CE QU'IL FAUT RETENIR
L'injection CRLF est rarement une vulnérabilité isolée. C'est une primitive qui peut être chaînée en XSS, request smuggling, empoisonnement de cache, et plus encore. Explorez toujours ce que vous pouvez faire d'autre avec avant de rédiger votre rapport.
[RÉFÉRENCES]
[ARTICLES_LIÉS]
Consultez mes autres articles
→ De Self-XSS à XSS Réfléchi via CSRF
→ Analyse IDOR : Cas Réels