Temps de lecture estimé: 4 minutes
Si comme moi tu t’es déjà retrouvé dans la situation d’inclure accidentellement un mot de passe dans un commit sur git, tu t’es peux être aussi demandé comment le retirer, surtout si ton dépôt est public.
Il faut le retirer du fichier bien entendu, mais aussi et surtout de tout l’historique git (sinon ça ne sert à rien)
Pour ça j’ai utilisé un utilitaire qui s’appelle BFG Repo-Cleaner, alternative apparemment beaucoup plus simple et beaucoup plus rapide que d’utiliser la commande git-filter-branch (je n’ai pas testé la méthode avec git-filter-branch)
Avec BFG Repo-Cleaner on peut retirer une occurrence d’un texte (des données sensibles comme un mot de passe et/ou un login) dans un fichier, on peut aussi simplement supprimer un fichier ou tout un dossier de tout l’historique de dépôt et il peut aussi être utilisé pour alléger le dépôt et supprimer tous les médias un peu lourds qui ont été inclus dans le dépôt (ce qui est un peu cracra mais des fois, on à pas le choix!! et puis … qui ne l’a jamais fait !?! )
Bref, dans mon cas c’était un mot de passe et un login dans un fichier de configuration. Pour illustrer cet article j’ai créé un repo git dans lequel j’ai un fichier readme.md qui contient plusieurs fois un mot de passe ( azerty25; ) que j’ai introduit plusieurs fois dans plusieurs commit de différentes branches
allons y donc pour supprimer un mot de passe ou une donnée sensible d’un dépôt git
Disclaimer
Attention, la réécriture de tout l’historique git est une cascade périlleuse, à tes risques et périls. Alors on s’assure bien entendu d’avoir un backup au cas où et on prévient ses p’tits potes si on bosse en équipe.
D’ailleurs, après l’opération, il est “conseillé”/obligatoire de cloner à nouveau le dépôt au lieu d’essayer de le mettre à jour avec un pull
Telecharger BFG Repo-Cleaner
L’utilitaire est développé en Scala et disponible en archive Java .jar sur github.
Il faut donc java pour l’exécuter, dans mon cas il est déjà installé et disponible dans ma console
java -version
java version "1.8.0_351"
Java(TM) SE Runtime Environment (build 1.8.0_351-b10)
Java HotSpot(TM) 64-Bit Server VM (build 25.351-b10, mixed mode)
du coup pour utiliser la commande BFG Repo Cleaner:
java -jar bfg-1.14.0.jar
Supprimer manuellement le mot de passe
Avant de réécrire l’historique de git, il faut supprimer manuellement le mot de passe dans le ou les fichiers sous peine que le mot de passe se retrouve dans un commit protégé (comme le HEAD) et ne soit finalement pas totalement supprimé du dépôt
dans mon cas par exemple, BFG m’a alerté
Protected commits
-----------------
These are your protected commits, and so their contents will NOT be altered:
* commit becad5a1 (protected by 'HEAD') - contains 1 dirty file :
- readme.md (304 B )
WARNING: The dirty content above may be removed from other commits, but as
the *protected* commits still use it, it will STILL exist in your repository.
Details of protected dirty content have been recorded here :
C:\Users\antho\dev_workspace\remove-sensitive-data-git.git.bfg-report\2022-12-13\18-34-07\protected-dirt\
If you *really* want this content gone, make a manual commit that removes it,
and then run the BFG on a fresh copy of your repo.
je fais donc le nécessaire pour supprimer le mot de passe manuellement
Cloner le dépôt git
pour faire ça proprement, on clone une copie fraiche et sans surplus du repo git avec l’option –mirror . Ce paramètre permet d’avoir une copie complète de tout le dépôt, l’historique / le référentiel git sans avoir les fichiers.
git clone --mirror https://gitlab.anthony-jacob.com/anthony.jacob/remove-sensitive-data-git.git
Créer un fichier texte des informations à supprimer
Il faut ensuite mettre tous les textes à supprimer dans un fichier texte, passwords.txt par exemple. Ce fichier doit contenir une occurrence par ligne. Par défaut le texte à supprimer sera remplacé par **REMOVED**.
Si tu souhaites remplacer par un texte personnalisé, c’est possible en ajoutant ==> suivit du texte de remplacement voulut à la fin des lignes.
azerty25;==>** supprimé **
Supprimer le mot de passe et réécrire l’historique git
Maintenant, il suffit juste de lancer la commande:
java -jar bfg-1.14.0.jar --replace-text passwords.txt remove-sensitive-data-git.git
si tout ce passe bien, tu devrais avoir un récap de ce qu’il s’est passé: s’il y a des commits protégés, quels commits/fichiers/branches sont impactés dans mon cas:
Using repo : C:\Users\antho\dev_workspace\remove-sensitive-data-git.git
Found 2 objects to protect
Found 3 commit-pointing refs : HEAD, refs/heads/feature/feature-avec-mot-de-passe, refs/heads/main
Protected commits
-----------------
These are your protected commits, and so their contents will NOT be altered:
* commit a880d7b6 (protected by 'HEAD')
Cleaning
--------
Found 6 commits
Cleaning commits: 100% (6/6)
Cleaning commits completed in 327 ms.
Updating 2 Refs
---------------
Ref Before After
------------------------------------------------------------------
refs/heads/feature/feature-avec-mot-de-passe | 55ca088c | 24b88156
refs/heads/main | a880d7b6 | 4ec00857
Updating references: 100% (2/2)
...Ref update completed in 21 ms.
Commit Tree-Dirt History
------------------------
Earliest Latest
| |
. . D D D m
D = dirty commits (file tree fixed)
m = modified commits (commit message or parents changed)
. = clean commits (no changes to file tree)
Before After
-------------------------------------------
First modified commit | 13852be7 | 1a9538de
Last dirty commit | becad5a1 | d0c37d14
Changed files
-------------
Filename Before & After
-------------------------------------------------------------------------
readme.md | 87e95e43 ? 4c7e0cbf, 973dcd3e ? 67b36f9a, d5644f49 ? 33aba860
In total, 7 object ids were changed. Full details are logged here:
C:\Users\antho\dev_workspace\remove-sensitive-data-git.git.bfg-report\2022-12-13\18-48-54
BFG run is complete! When ready, run: git reflog expire --expire=now --all && git gc --prune=now --aggressive
ensuite, comme demandé, va réécrire le journal des références / reflogs avec:
cd remove-sensitive-data-git.git
puis
git reflog expire --expire=now --all && git gc --prune=now --aggressive
et pour finir, on pousse tout ça sur le serveur:
git push --force
(dans mon cas j’ai temporairement autorisé le push –force dans les Paramètres\Dépôt\Branches protégées de mon projet sur Gitlab)
Et voilà !! comme on peut le voir ici sur le fichier, maintenant le mot de passe a été supprimé de tout l’historique git
Voilà j’espère que cet article a pu t’aider !
en attendant, je te dis à bientôt dans de nouvelles aventures!