Skip to main content

Entfernen vertraulicher Daten aus einem Repository

Wenn du vertrauliche Daten wie Passwörter oder SSH-Schlüssel in ein Git-Repository überträgst, kannst du sie aus dem Verlauf entfernen. Du kannst unerwünschte Dateien mit dem Tool git filter-repo oder dem Open-Source-Tool „BFG Repo-Cleaner“ vollständig aus dem Verlauf eines Repositorys entfernen.

Das Tool git filter-repo und der BFG Repo-Cleaner generieren einen neuen Verlauf deines Repositorys, wodurch die SHAs für vorhandene Commits, die du bearbeitest, und alle abhängigen Commits geändert werden. Geänderte Commit-SHAs können sich auf offene Pull Requests in deinem Repository auswirken. Wir empfehlen, alle geöffneten Pull Requests zusammenzuführen oder zu schließen, bevor du Dateien aus deinem Repository entfernst.

Du kannst die Datei mit git rm aus dem letzten Commit entfernen. Informationen zum Entfernen einer Datei, die mit dem letzten Commit hinzugefügt wurde, findest du unter Informationen zu großen Dateien auf GitHub.

Warnung: In diesem Artikel erfährst du, wie du Commits mit vertraulichen Daten so konfigurierst, dass diese über keinen Branch oder Tag in deinem Repository auf GitHub.com erreichbar sind. Nicht verhindern lässt sich dadurch jedoch, dass diese Commits nach wie vor in Klonen oder Forks deines Repositorys, in zwischengespeicherten Ansichten auf GitHub direkt über ihre SHA-1-Hashes und über alle referenzierten Pull Requests zugänglich sind. Du kannst vertrauliche Daten nicht aus Klonen entfernen, die andere Benutzer von deinem Repository erstellt haben, aber du kannst zwischengespeicherte Ansichten und Verweise auf die vertraulichen Daten in Pull Requests auf GitHub über den uns über das GitHub-Support-Portal dauerhaft entfernen lassen. GitHub-Support helfen nur bei der Entfernung vertraulicher Daten in Fällen, in denen wir feststellen, dass das Risiko nicht durch Drehen betroffener Anmeldeinformationen entschärft werden kann.

Sobald du einen Commit an GitHub gepusht hast, solltest du alle vertraulichen Daten im Commit als kompromittiert betrachten. Wenn der Commit ein Kennwort enthielt, ändere es. Wenn der Commit einen Schlüssel enthielt, generiere einen neuen. Durch das Entfernen der kompromittierten Daten wird die ursprüngliche Offenlegung nicht behoben, insbesondere nicht in vorhandenen Klonen oder Forks deines Repositorys.

Wenn der Commit, über den die vertraulichen Daten eingeführt wurden, in irgendeinem Fork deines Repositorys noch vorhanden ist, sind die Daten weiterhin zugänglich, es sei denn, derdie Forkbesitzerin entfernt sie auch aus seinemihrem Fork oder löscht den Fork vollständig. Du musst dich mit den Besitzerinnen aller Forks deines Repositorys abstimmen und sie bitten, die entsprechenden Maßnahmen zu ergreifen. Beachte, dass GitHub keine Kontaktdaten für diese Besitzer*innen bereitstellen kann.

Berücksichtige diese Einschränkungen und Herausforderungen bei deiner Entscheidung, den Verlauf deines Repositorys neu zu generieren.

Datei aus dem Verlauf deines Repositorys löschen

Du kannst eine Datei endgültig aus dem Verlauf deines Repositorys löschen, indem du entweder das Tool git filter-repo oder das Open-Source-Tool BFG Repo-Cleaner verwendest.

Hinweis: Wenn sich vertrauliche Daten in einer Datei befinden, die als Binärdatei identifiziert wird, musst du die Datei aus dem Verlauf entfernen, da du sie nicht ändern kannst, um die Daten zu entfernen oder zu ersetzen.

Benutze BFG

Der BFG Repo-Cleaner ist ein von der Open-Source-Community entwickeltes und verwaltetes Tool. Es stellt eine schnellere und einfachere Alternative zu git filter-repo dar, um unerwünschte Daten zu entfernen.

Um beispielsweise deine Datei mit vertraulichen Daten zu entfernen und deinen letzten Commit unberührt zu lassen, führe folgenden Befehl aus:

bfg --delete-files YOUR-FILE-WITH-SENSITIVE-DATA

Um den gesamten, in passwords.txt enthaltenen Text dort zu ersetzen, wo er im Verlauf deines Repositorys aufgeführt ist, musst du folgenden Code ausführen:

bfg --replace-text passwords.txt

Nachdem die vertraulichen Daten entfernt wurden, musst du einen Push deiner Änderungen an GitHub erzwingen. Durch den erzwungenen Push wird der Repositoryverlauf neu generiert, wodurch vertrauliche Daten aus dem Commitverlauf entfernt werden. Wenn du einen Push erzwingst, werden möglicherweise Commits überschrieben, auf denen andere Personen ihre Arbeit aufgebaut haben.

git push --force

Informationen zur vollständigen Verwendung sowie eine Downloadanleitung findest du in der Dokumentation für BFG Repo-Cleaner.

Verwenden von „git filter-repo“

Warnung: Wenn du git filter-repo nach dem Stashen von Änderungen ausführst, ist es nicht länger möglich, deine Änderungen über andere Stashbefehle erneut abzurufen. Vor dem Ausführen von git filter-repo solltest du den Stash aufheben, den du für deine vorgenommenen Änderungen ausgeführt hast. Führe git stash show -p | git apply -R aus, um deinen letzten Stash aufzuheben. Weitere Informationen findest du unter Git Tools – Stashen und Bereinigen.

Um zu veranschaulichen, wie git filter-repo funktioniert, zeigen wir dir, wie du deine Datei mit vertraulichen Daten aus dem Verlauf deines Repositorys entfernst und .gitignore hinzufügst, um sicherzustellen, dass sie nicht versehentlich erneut committet wird.

  1. Installiere die neueste Version des Tools git filter-repo. Du kannst git-filter-repo manuell oder mithilfe eines Paket-Managers installieren. Verwenden Sie beispielsweise den Befehl brew install, um das Tool mit HomeBrew zu installieren.

    brew install git-filter-repo
    

    Weitere Informationen findest du in INSTALL.md im Repository newren/git-filter-repo.

  2. Wenn Sie keine lokale Kopie des Repositorys mit den vertraulichen Daten im Verlauf haben, müssen Sie das Repository auf Ihrem lokalen Computer klonen.

    $ git clone https://github.com/YOUR-USERNAME/YOUR-REPOSITORY
    > Initialized empty Git repository in /Users/YOUR-FILE-PATH/YOUR-REPOSITORY/.git/
    > remote: Counting objects: 1301, done.
    > remote: Compressing objects: 100% (769/769), done.
    > remote: Total 1301 (delta 724), reused 910 (delta 522)
    > Receiving objects: 100% (1301/1301), 164.39 KiB, done.
    > Resolving deltas: 100% (724/724), done.
    
  3. Navigiere zum Arbeitsverzeichnis des Repositorys.

    cd YOUR-REPOSITORY
    
  4. Führe den folgenden Befehl aus, und ersetze PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA durch den Pfad zur Datei, die du entfernen möchtest, nicht nur durch den Dateinamen. Diese Argumente werden:

    • erzwingen, dass Git den gesamten Verlauf eines jeden Branchs und Tags verarbeitet, ohne ihn auszuchecken

    • die angegebene Datei sowie alle leeren Commits entfernen, die als Ergebnis generiert wurden

    • einige Konfigurationen entfernen, wie zum Beispiel die Remote-URL, die in der Datei .git/config gespeichert ist Du solltest diese Datei zur späteren Wiederherstellung im Voraus sichern.

    • vorhandene Tags überschreiben

        $ git filter-repo --invert-paths --path PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA
        Parsed 197 commits
        New history written in 0.11 seconds; now repacking/cleaning...
        Repacking your repo and cleaning out old unneeded objects
        Enumerating objects: 210, done.
        Counting objects: 100% (210/210), done.
        Delta compression using up to 12 threads
        Compressing objects: 100% (127/127), done.
        Writing objects: 100% (210/210), done.
        Building bitmaps: 100% (48/48), done.
        Total 210 (delta 98), reused 144 (delta 75), pack-reused 0
        Completely finished after 0.64 seconds.
      

    Hinweis: Wenn die Datei mit vertraulichen Daten in weiteren Pfaden enthalten war (weil sie verschoben oder umbenannt wurde), musst du diesen Befehl auch für diese Pfade ausführen.

  5. Füge deine Datei mit vertraulichen Daten zu .gitignore hinzu, um sicherzustellen, dass du sie nicht versehentlich erneut committest.

    $ echo "YOUR-FILE-WITH-SENSITIVE-DATA" >> .gitignore
    $ git add .gitignore
    $ git commit -m "Add YOUR-FILE-WITH-SENSITIVE-DATA to .gitignore"
    > [main 051452f] Add YOUR-FILE-WITH-SENSITIVE-DATA to .gitignore
    >  1 files changed, 1 insertions(+), 0 deletions(-)
    
  6. Überprüfen Sie noch einmal, ob Sie alles Gewünschte aus dem Verlauf Ihres Repositorys entfernt haben und ob alle Ihre Branches ausgecheckt sind.

  7. Das Tool git filter-repo entfernt Ihre konfigurierten Remotes automatisch. Verwenden Sie den Befehl git remote set-url, um Ihre Remotes wiederherzustellen, und ersetzen Sie dabei OWNER und REPO durch Ihre Repository-Details. Weitere Informationen findest du unter Remote-Repositorys verwalten.

    git remote add origin https://github.com/OWNER/REPOSITORY.git
    
  8. Wenn du mit dem Zustand deines Repositorys zufrieden bist, und du das entsprechende Remoterepository gesetzt hast erzwinge einen Push deiner lokalen Änderungen, um dein Repository auf GitHub.com zu überschreiben, ebenso wie alle von dir gepushten Branches. Ein erzwungener Push ist erforderlich, um vertrauliche Daten aus deinem Commitverlauf zu entfernen.

    $ git push origin --force --all
    > Counting objects: 1074, done.
    > Delta compression using 2 threads.
    > Compressing objects: 100% (677/677), done.
    > Writing objects: 100% (1058/1058), 148.85 KiB, done.
    > Total 1058 (delta 590), reused 602 (delta 378)
    > To https://github.com/YOUR-USERNAME/YOUR-REPOSITORY.git
    >  + 48dc599...051452f main -> main (forced update)
    
  9. Um die vertrauliche Datei aus Deinen getaggten Releases zu entfernen, musst du auch einen Push für deine Git-Tags erzwingen:

    $ git push origin --force --tags
    > Counting objects: 321, done.
    > Delta compression using up to 8 threads.
    > Compressing objects: 100% (166/166), done.
    > Writing objects: 100% (321/321), 331.74 KiB | 0 bytes/s, done.
    > Total 321 (delta 124), reused 269 (delta 108)
    > To https://github.com/YOUR-USERNAME/YOUR-REPOSITORY.git
    >  + 48dc599...051452f main -> main (forced update)
    

Vollständiges Entfernen der Daten aus GitHub

Nachdem du die vertraulichen Daten entweder mit dem BFG-Tool oder mit git filter-repo entfernt und deine Änderungen in GitHub gepusht hast, musst du noch einige weitere Schritte ausführen, um die Daten vollständig aus GitHub zu entfernen.

  1. Kontaktieren Sie den uns über das GitHub-Support-Portal, und bitten Sie darum, zwischengespeicherte Ansichten und Referenzen auf die sensiblen Daten in Pull Requests auf GitHub zu entfernen. Geben Sie bitte den Namen des Repositorys und/oder einen Link zu dem Commit an, der entfernt werden soll.

    Hinweis: GitHub-Support entfernt keine nicht vertraulichen Daten und hilft nur bei der Entfernung vertraulicher Daten in Fällen, in denen wir feststellen, dass das Risiko nicht durch Drehen betroffener Anmeldeinformationen verringert werden kann.

  2. Teile deinen Projektmitarbeitern, dass sie für alle Branches, die sie aus deinem alten (nicht mehr gültigen) Repositoryverlauf erstellt haben, ein Rebase, keinen Merge durchführen sollen. Durch einen Merge-Commit würde womöglich der gesamte unbrauchbare Verlauf wiederhergestellt, den zu entfernen du Dir gerade so viel Mühe gemacht hast.

  3. Nachdem etwas Zeit vergangen ist und du dir sicher bist, dass das BFG-Tool/git filter-repo keine unbeabsichtigten Nebenwirkungen verursacht hat, kannst du mithilfe der folgenden Befehle erzwingen, dass Verweise auf alle Objekte in deinem lokalen Repository aufgehoben werden und eine Garbage Collection durchgeführt wird (bei Verwendung von Git 1.8.5 oder höher):

    $ git for-each-ref --format="delete %(refname)" refs/original | git update-ref --stdin
    $ git reflog expire --expire=now --all
    $ git gc --prune=now
    > Counting objects: 2437, done.
    > Delta compression using up to 4 threads.
    > Compressing objects: 100% (1378/1378), done.
    > Writing objects: 100% (2437/2437), done.
    > Total 2437 (delta 1461), reused 1802 (delta 1048)
    

    Hinweis: Du kannst dies auch erreichen, indem du deinen gefilterten Verlauf in ein neues oder leeres Repository pushst und dann einen neuen Klon von GitHub erstellst.

Versehentliche Commits künftig vermeiden

Indem du verhinderst, dass Mitwirkende versehentlich Commits ausführen, kannst du die Offenlegung vertraulicher Informationen verhindern. Weitere Informationen findest du unter Best Practices zum Verhindern von Datenlecks in deiner Organisation.

Durch einige einfache Tricks vermeidest du den versehentlichen Commit von Änderungen, die nicht festgeschrieben werden sollen:

  • Verwende ein visuelles Programm wie GitHub Desktop oder gitk, um die Änderungen zu committen. In visuellen Programmen ist meist leichter erkennbar, welche Dateien durch einen Commit hinzugefügt, gelöscht und geändert werden.
  • Vermeide die allgemeingültigen Befehle git add . und git commit -a für die Befehlszeile – verwende stattdessen git add filename und git rm filename, um die Dateien einzeln bereitzustellen.
  • Verwende git add --interactive, um die Änderungen in jeder Datei einzeln zu überprüfen und zu stagen.
  • Verwende git diff --cached, um die für den Commit gestageten Änderungen zu überprüfen. Das ist genau der Unterschied, den git commit erzeugt, solange du nicht das -a Flag verwendest.

Weiterführende Themen