# Dossier .git public : une fuite de données sous-estimée

> Votre dossier .git est-il public ? Comment le vérifier, bloquer l'accès, adapter le déploiement et traiter les identifiants présents dans l'historique.

Source : https://phpsos.de/fr/blog/git-ordner-oeffentlich/  
État : 25/10/2026  
Fournisseur : PHP SOS, Assistance d'urgence PHP et sécurité des serveurs. Aide immédiate par WhatsApp : https://wa.me/491736494914?text=Bonjour%20PHP%20SOS%2C%20nous%20avons%20besoin%20d%27aide%20avec%20notre%20serveur%20PHP.%20Entreprise%20%3A%20%E2%80%A6%20Site%20web%20%3A%20%E2%80%A6

**En bref :** un dossier .git public apparaît lorsqu'un site est déployé par `git clone` ou `git pull` directement dans le webroot et que le serveur web ne bloque pas les dossiers cachés. Tout le code source peut alors être récupéré avec son historique, y compris des identifiants versionnés par le passé. Vérifiez vos domaines par un simple appel, bloquez immédiatement l'accès, faites passer le déploiement à des paquets sans `.git` et remplacez les identifiants figurant dans l'historique.

## Le code source à emporter

Git est l'outil standard de gestion de versions, et pour de petites équipes, il est naturel de s'en servir aussi pour déployer : se connecter au serveur, `git pull`, terminé. Cela fonctionne de façon fiable et rapide. Mais cela a un effet secondaire que personne ne remarque souvent.

Dans le dossier du projet se trouve un dossier caché `.git`. Il contient non seulement l'état actuel, mais chaque fichier dans chaque version jamais versionnée, ainsi que les messages de commit, les noms et adresses e-mail des développeurs et des références à des serveurs. Si ce dossier se trouve dans le webroot et que le serveur web le diffuse, n'importe qui peut le récupérer.

Pour les attaquants, c'est un cadeau. Avec le code source, on peut chercher des vulnérabilités de façon ciblée au lieu de les deviner de l'extérieur. Et l'historique contient souvent des choses qui semblaient depuis longtemps supprimées : un mot de passe de base de données des débuts, une clé d'API, un fichier de test avec des données clients.

## Votre dossier .git est-il public ? Comment le vérifier

La vérification prend quelques secondes et ne modifie rien. Pour chaque domaine et sous-domaine, appelez un fichier qui existe dans tout dépôt Git :

```bash
# Attendu : 403 ou 404
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/.git/HEAD
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/.git/config
# Sur le serveur : existe-t-il des dossiers .git sous les webroots ?
find /var/www /srv/www -maxdepth 4 -type d -name ".git" 2>/dev/null
```

Un statut 200 signifie que le dossier est accessible. Faites aussi attention aux sous-répertoires. Parfois, le dépôt ne se trouve pas dans le webroot lui-même, mais dans un dossier d'extension ou de thème géré séparément avec Git.

Vérifiez également les environnements de préproduction et de test. Ils sont mis à jour plus souvent avec Git que la production et sont fréquemment accessibles sous des sous-domaines faciles à deviner.

## Immédiatement : bloquer l'accès

Tant que le déploiement n'est pas modifié, une règle dans le serveur web bloque l'accès aux dossiers de gestion de versions. Un blocage général des fichiers cachés, tel que décrit dans [Bien protéger les identifiants et les fichiers .env](https://phpsos.de/fr/blog/env-dateien-schuetzen/), couvre aussi ce cas. Pour ne bloquer que la gestion de versions, utilisez une règle plus étroite :

```nginx
location ~ /\.(git|svn|hg)(/|$) {
    return 404;
}
```

```apache
RedirectMatch 404 /\.(git|svn|hg)(/|$)
```

Répétez ensuite la vérification ci-dessus, avec un véritable appel depuis l'extérieur : un test de configuration réussi indique seulement que la syntaxe est correcte, pas que la règle s'applique avant d'autres règles pour les fichiers statiques. Avec des panneaux comme Plesk ou cPanel, placez la règle dans les directives supplémentaires prévues à cet effet, afin qu'elle ne soit pas perdue lors de la prochaine génération de configuration.

> **Agir immédiatement:**
> Si le dossier était accessible, traitez comme connus tous les identifiants qui ont figuré un jour dans le dépôt. Le blocage seul ne suffit alors pas, les valeurs doivent être remplacées.

## Durablement : déployer sans .git dans le webroot

Le blocage est une protection, pas une solution. À long terme, la gestion de versions n'a pas sa place sur le serveur de production. Voies éprouvées, selon votre environnement :

| Procédé | Fonctionnement | Adapté à |
|---|---|---|
| Paquet de build issu de la CI | Le pipeline construit une archive sans `.git`, le serveur la décompresse dans un nouveau répertoire de release | Équipes avec CI/CD |
| `git archive` | produit une archive d'un état sans données de version | petits projets sans pipeline |
| `rsync` avec exclusions | ne transfère que les fichiers nécessaires | serveurs classiques |
| Image de conteneur | Le code est copié dans l'image à la construction, `.git` exclu via `.dockerignore` | exploitation en conteneurs |

Un répertoire de release par version, avec un lien symbolique vers l'état actuel, présente un autre avantage : en cas de problème, vous pouvez revenir en arrière immédiatement. Pour les configurations en conteneurs, [CI/CD : reconstruire automatiquement les images PHP](https://phpsos.de/fr/blog/php-images-in-ci-neu-bauen/) décrit comment rendre les builds reproductibles. Il faut aussi y vérifier que `.git` n'arrive pas dans l'image.

```bash
# Exemple : produire un paquet d'un état sans données de version
git archive --format=tar.gz -o release.tar.gz HEAD
```

## Autres fichiers de projet qui n'ont pas leur place dans le webroot

Le dossier `.git` est l'exemple le plus connu, mais pas le seul. Qui déploie des répertoires de projet entiers amène dans le webroot d'autres fichiers qui n'ont rien à y faire :

- Les dossiers d'environnements de développement comme `.idea` ou `.vscode`, dans lesquels des extensions de téléversement de fichiers stockent parfois des adresses de serveurs et des identifiants.
- `composer.json` et `composer.lock`, qui révèlent les versions exactes de toutes les bibliothèques et facilitent ainsi la recherche de failles connues.
- Les configurations de tests, d'outils de build et de pipelines, qui exposent des noms d'hôte et des processus internes.
- Les vestiges de systèmes d'exploitation comme `.DS_Store`, qui contiennent les listes de fichiers de répertoires entiers.

La solution est la même que pour le dossier `.git` : ne diffuser que ce qui doit être public, idéalement via un sous-dossier dédié comme webroot. Qui fait de toute façon passer le déploiement à des paquets définit du même coup une liste de fichiers exclus et la revoit à chaque nouvel outil du projet.

## Si le dossier était ouvert : examiner l'historique et les journaux

S'il s'avère que le dossier `.git` était accessible, procédez dans cet ordre :

1. **Bloquer l'accès** et répéter la vérification.
2. **Parcourir l'historique** pour voir quels secrets ont jamais été versionnés : fichiers de configuration, `.env`, clés, dumps de base de données.
3. **Remplacer les identifiants**, tous ceux trouvés à l'étape 2, même s'ils ne figurent plus aujourd'hui dans le code.
4. **Analyser les journaux d'accès** pour voir si des fichiers sous `/.git/` ont été appelés avec le statut 200 et depuis quelles adresses. La marche à suivre est montrée dans [Analyser les journaux du serveur web après une attaque](https://phpsos.de/fr/ratgeber/logfiles-auswerten/).
5. **Examiner le code source de façon ciblée**, car les attaquants le connaissent désormais. Les faiblesses connues devraient être corrigées en priorité.
6. **Clarifier la protection des données**, si des données personnelles figuraient dans l'historique, par exemple des exports de test. L'évaluation revient à votre délégué à la protection des données.

Des outils de recherche de secrets dans les dépôts doivent ensuite entrer durablement dans le pipeline. L'OWASP recommande expressément de tels contrôles, comme hook avant le versionnement et dans la CI.

## Comment PHP SOS aide-t-il concrètement ?

- Nous vérifions tous vos domaines et sous-domaines à la recherche de dossiers de gestion de versions accessibles.
- Nous bloquons immédiatement l'accès et faisons passer le déploiement à des paquets sans données de version.
- Nous parcourons l'historique à la recherche de secrets et accompagnons le remplacement des accès concernés.
- Nous analysons les journaux d'accès et documentons si et quand des données ont été appelées.

Ces mesures font partie de notre [durcissement de serveur pour serveurs web PHP](https://phpsos.de/fr/leistungen/server-haertung/).


## Questions fréquentes

**Comment un dossier .git public apparaît-il ?**  
Le plus souvent par un déploiement via git clone ou git pull directement dans le webroot. Le dossier .git, avec tout l'historique des versions, se trouve alors à côté de index.php et, sans blocage, le serveur web diffuse ses fichiers.

**Suffit-il de supprimer le dossier .git ?**  
Pour l'avenir, oui ; pour le passé, non. Si le dossier était accessible, son contenu a peut-être déjà été copié. Vous devriez donc remplacer les identifiants qui ont figuré à un moment ou à un autre dans le dépôt.

**Supprimer après coup les identifiants de l'historique Git aide-t-il ?**  
Cela empêche que de nouvelles copies les contiennent. Quiconque a déjà récupéré le dépôt possède toujours les anciennes versions. Ce qui compte, c'est donc de remplacer les identifiants, et pas seulement de réécrire l'historique.

**Cela concerne-t-il aussi d'autres gestionnaires de versions ?**  
Oui. Des dossiers comme .svn ou .hg contiennent eux aussi des données de projet et ne devraient jamais être accessibles dans le webroot. Un blocage général des fichiers et dossiers commençant par un point couvre tous ces cas.

## Sources

- [Aide-mémoire OWASP sur la gestion des secrets (Secrets Management Cheat Sheet)](https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html)
- [Documentation de Nginx](https://nginx.org/en/docs/)
- [Serveur HTTP Apache : documentation](https://httpd.apache.org/docs/)
