Dépôt .git exposé : reconstruire les sources d'une application
Un dossier .git laissé accessible à la racine d’un site expose bien plus que le code en production. Il contient l’historique complet du dépôt, les branches, les commits et chaque version des fichiers. À partir de là, on reconstruit les sources entières de l’application, y compris ce qui n’était pas censé être publié : secrets, clés, fichiers de configuration supprimés dans un commit ultérieur.
Ce que trahit un dossier .git
Section intitulée « Ce que trahit un dossier .git »Il ne faut jamais laisser le .git accessible, ni même l’embarquer dans une image ou une archive de déploiement. Sa présence expose la totalité du dépôt et permet d’en reconstruire le contenu.
Quelques éléments internes suffisent à comprendre la structure :
HEADpointe sur la branche ou le commit courant. C’est le point d’entrée pour savoir où l’on se trouve dans l’historique.refs/etpacked-refslistent les branches et les tags, avec le commit sur lequel chacun pointe. On voit ainsi tout ce qui a été livré.objects/contient les objets Git, la matière première. C’est lui qui permet de dumper l’intégralité des sources et de les reconstruire, pour ensuite naviguer entre branches et commits.
Vérifier l’exposition
Section intitulée « Vérifier l’exposition »Un simple accès au fichier HEAD confirme la présence du dépôt :
curl -s http://exemple.fr/.git/HEAD# ref: refs/heads/master → le .git est exposéSi le serveur autorise le listing de répertoire, http://exemple.fr/.git/ affiche directement l’arborescence. Le plus souvent, le listing est désactivé mais les fichiers restent accessibles un par un, ce que les outils suivants exploitent.
Dumper le dépôt avec GitTools
Section intitulée « Dumper le dépôt avec GitTools »GitTools regroupe les scripts adaptés à ce scénario.
git clone https://github.com/internetwache/GitTools.gitLe script Dumper récupère tout le dossier .git localement, en devinant et téléchargeant les fichiers internes un à un lorsque le listing est désactivé :
./GitTools/Dumper/gitdumper.sh http://exemple.fr/.git/ ./dumpReconstruire les sources
Section intitulée « Reconstruire les sources »Le script Extractor rejoue chaque commit récupéré et reconstruit l’arborescence des fichiers à chaque état de l’historique :
./GitTools/Extractor/extractor.sh ./dump ./commitsChaque commit est déplié dans un sous-dossier de ./commits, ce qui permet de retrouver les sources et de comparer les états successifs. C’est souvent dans un commit intermédiaire, avant qu’un secret ne soit « retiré », qu’on trouve la donnée sensible.
Le cas des fichiers .idx et .pack
Section intitulée « Le cas des fichiers .idx et .pack »Git ne stocke pas toujours ses objets un par un. Pour économiser de la place, il regroupe périodiquement de nombreux objets dans un packfile, ce qui donne un couple de fichiers dans objects/pack/ :
.packcontient les objets compressés et deltifiés ensemble. Plutôt que de stocker chaque version d’un fichier en entier, Git n’enregistre que les différences par rapport à une version de référence..idxest l’index du pack. Il associe chaque empreinte d’objet à sa position dans le.pack, pour que Git retrouve un objet sans parcourir tout le fichier.
Quand le dump ne ramène que ces fichiers, on reconstruit le dépôt à la main. On initialise un dépôt vide :
git initOn déplace les fichiers téléchargés dans le sous-dossier interne que Git vient de créer :
mv pack-89a81675f*.pack pack-89a81675f*.idx .git/objects/pack/Puis on demande à Git de reconstruire l’arborescence complète à partir du pack :
git fsck --fullgit fsck vérifie la cohérence de la base d’objets et signale les objets accessibles, y compris les commits « pendants ». On peut ensuite jongler entre branches et commits avec git log, git checkout et git show pour extraire les sources.
Remédiation
Section intitulée « Remédiation »Bloquer l’accès au dossier .git
Section intitulée « Bloquer l’accès au dossier .git »Le dossier .git n’a rien à faire dans la racine servie. La correction de fond est de déployer sans lui, mais une défense en profondeur bloque son accès au niveau du serveur.
# Nginxlocation ~ /\.git { deny all; return 404;}# Apache, .htaccessRedirectMatch 404 /\.gitDéployer un artefact propre
Section intitulée « Déployer un artefact propre »Le déploiement ne doit pas embarquer le dépôt. Exporter une arborescence sans historique élimine le problème à la source :
# Extraire les fichiers suivis, sans le .gitgit archive --format=tar HEAD | tar -x -C /var/www/monappNe jamais committer de secret
Section intitulée « Ne jamais committer de secret »Un .git exposé ne livre des secrets que s’il en contient. Garder les clés et mots de passe hors du dépôt (variables d’environnement, gestionnaire de secrets) et scanner l’historique limite l’impact d’une exposition.
À retenir
Section intitulée « À retenir »Un .git accessible sur un serveur web équivaut à publier le dépôt entier, historique compris. HEAD et refs/ révèlent la structure, objects/ permet de tout reconstruire, y compris les fichiers supprimés dans un commit ultérieur. La reconstruction est automatisée par GitTools, et même réduit à un couple .pack / .idx, le dépôt se réassemble avec git fsck. La seule vraie parade est de ne jamais servir ce dossier.