- Sur les systèmes de type Unix, cloner un dépôt non fiable avec
git clone --recursive peut permettre une exécution de code à distance via CVE-2025-48384 ; il faut donc mettre à jour Git ainsi que les logiciels intégrant Git
- La cause vient d’une différence de traitement du retour chariot (
\r) lors de la lecture puis de la réécriture de la configuration Git, ce qui crée un décalage entre la valeur validée et la valeur réellement utilisée
- En ajoutant un
\r à la fin du path d’un sous-module dans .gitmodules, le chemin de checkout peut devenir différent après validation
- Windows n’est pas directement vulnérable, car les caractères de contrôle ne sont pas autorisés dans les noms de fichiers, mais macOS est vulnérable à la fois à CVE-2024-32002 et à CVE-2025-48384
- Le correctif modifie l’écriture des valeurs de configuration contenant
\r pour les entourer de guillemets, bloquant ainsi des vecteurs d’attaque comme l’écriture de fichiers dans .git et la création de hooks Git
Présentation de la vulnérabilité et mesures immédiates
- CVE-2025-48384 est une vulnérabilité de Git pouvant mener à une exécution de code à distance lorsqu’un dépôt non fiable est cloné avec
git clone --recursive sur des plateformes de type Unix
- Il faut mettre à jour vers une version corrigée de Git et également mettre à jour les logiciels embarquant Git, y compris GitHub Desktop
- En ligne de commande, exécuter uniquement
git clone ne clone pas automatiquement les sous-modules
- Pour atténuer le risque, on peut d’abord lancer
git clone sans --recursive, vérifier que .gitmodules est sûr, puis initialiser les sous-modules
- GitHub Desktop clone par défaut en mode récursif et peut donc être affecté dans ce scénario
Retour chariot et fichiers de configuration Git
- Le retour chariot est le caractère ASCII numéro 13, Carriage Return, représenté par
\r dans les chaînes C
- Unix a cherché à n’utiliser que LF, c’est-à-dire
\n, pour séparer les lignes, tandis que Windows et plusieurs protocoles Internet utilisent CR+LF, soit \r\n
- Le format de configuration de type
.ini utilisé par Git sert non seulement aux fichiers de configuration utilisateur, mais aussi au fichier .gitmodules inclus dans les dépôts
- Pour prendre en charge les fins de ligne DOS, l’analyseur de configuration Git se comporte ainsi lors de la lecture des caractères
- si le caractère courant est
\r, il examine le caractère suivant
- si le caractère suivant est
\n, il ignore \r et le traite comme un saut de ligne
- si le caractère suivant n’est pas
\n, il remet ce caractère dans le flux et renvoie \r
- Ce traitement s’applique ligne par ligne, donc si une ligne se termine par un CR, ce CR peut être supprimé indépendamment du format global du fichier
Incohérence entre lecture et écriture
- Git ne se contente pas de lire les fichiers de configuration : lorsqu’il écrit des valeurs, comme avec
git config, il enregistre aussi des paires key = value
- L’ancien code n’entourait la valeur de guillemets doubles que dans les cas suivants
- si la valeur commençait par un espace
- si elle contenait
; ou #
- si elle se terminait par un espace
- En revanche, le code de lecture de configuration prend en charge les chaînes entre guillemets ; ainsi, lorsqu’une valeur écrite par
write_pair est relue plus tard, le dernier \r peut disparaître
- Par exemple, si le fichier de configuration contient
key = "foo^M", il peut être réécrit ensuite sous la forme key = foo^M
- ici,
^M représente un caractère CR littéral
- Lorsque ce comportement est combiné à une valeur non fiable dans
.gitmodules, le traitement des chemins de sous-modules devient ambigu
Confusion sur les chemins de sous-modules et portée de l’impact
- Sur les systèmes de type Unix, il est possible d’insérer des caractères de contrôle dans les noms de fichiers, ce qui permet d’inclure un CR dans la valeur
path de .gitmodules
- Voici un exemple
[submodule "foo"]
path = "foo^M"
- Si cette valeur est écrite par le code de configuration Git dans
.git/modules/foo/config, elle peut prendre la forme suivante
[core]
workdir = ../../../foo^M
- La validation a déjà eu lieu sur le chemin non fiable lu depuis
.gitmodules
- Ensuite, si le dernier
\r est supprimé lors d’une nouvelle lecture de la configuration, Git utilise un chemin différent de celui qui a été validé
- En conséquence, pendant le clonage du sous-module, l’emplacement lu depuis
path = ... et l’emplacement réellement écrit et utilisé peuvent différer
- Ce principe est similaire à celui de CVE-2024-32002
- CVE-2024-32002 trompait Git via la sensibilité ou non à la casse dans un sous-module
- CVE-2025-48384 nécessite un système de fichiers autorisant les caractères de contrôle dans les noms de fichiers
- Windows n’est pas directement vulnérable à ce bug précis, car les caractères de contrôle ne sont pas autorisés dans les noms de fichiers
- macOS est vulnérable à la fois à CVE-2024-32002 et à CVE-2025-48384
Correctif et possibilités d’exploitation
- Le correctif modifie
write_pair afin d’entourer la chaîne de guillemets si la valeur contient \r
- Le changement est simple : il ajoute
'\r' à la condition qui ne vérifiait auparavant que ; ou #
for (i = 0; value[i]; i++)
- if (value[i] == ';' || value[i] == '#')
+ if (value[i] == ';' || value[i] == '#' || value[i] == '\r')
quote = "\"";
- Cette confusion de chemin permet de placer des fichiers malveillants d’un sous-module presque n’importe où dans le système de fichiers et, comme la validation est contournée, de suivre aussi des liens symboliques situés hors du dépôt
- Le mode d’exploitation le plus direct consiste à écrire un fichier dans le répertoire
.git et à créer un script de hook Git afin que Git exécute du code contrôlé par l’attaquant lors du déclenchement du hook
- Une autre possibilité est l’écrasement de
.git/config
- Aucun PoC n’a encore été publié, mais il est indiqué qu’une modification presque triviale de l’exploit de CVE-2024-32002 suffirait
- Le test du commit de correction peut donner de fortes indications sur la méthode d’attaque
Problèmes récurrents liés au CR et enseignements
- Ce n’est pas la première fois que le retour chariot provoque des problèmes dans Git
- En janvier, RyotaK a découvert un problème dans le protocole du credential helper pouvant être trompé par un retour chariot
- En 2023, André Baptista et Vítor Pinho ont découvert CVE-2023-29007, une erreur logique dans l’analyse de la configuration
- Cette vulnérabilité ne relève pas d’un problème propre au langage C, mais plutôt d’une erreur logique susceptible d’apparaître dans presque tous les langages
- Le point commun est qu’elle survient dans la communication inter-processus entre composants internes de Git, ou entre Git et des processus externes
- On peut y voir une structure semblable à celle des injections CRLF en HTTP, du request smuggling ou du SMTP smuggling
- Par le passé, Internet s’appuyait sur le principe de robustesse de Postel, « soyez conservateur dans ce que vous envoyez, libéral dans ce que vous acceptez », mais ce n’est peut-être plus le conseil le plus raisonnable aujourd’hui
- Le sujet est traité plus en détail dans RFC 9413
Remerciements et correctifs associés
- Cette vulnérabilité a été découverte dans le cadre d’un audit de Git
- D’autres bugs de gravité variable ont également été corrigés dans la même release
- G-Research Open Source a rendu ce travail possible
Aucun commentaire pour le moment.