Wie man vertrauliche Daten aus einem Repository entfernt
Wenn du den Verlauf deines Repositorys mithilfe von Tools wie git-filter-repo änderst, ist die Kenntnis über die Auswirkungen wichtig. Das Umschreiben der Geschichte erfordert eine sorgfältige Koordination mit Kollegen und hat eine Reihe von Nebenwirkungen, die verwaltet werden müssen.
Es ist wichtig zu beachten, dass es sich bei den vertraulichen Daten, die du entfernen musst, häufig um ein Geheimnis handelt (z. B. Kennwort/Token/Anmeldeinformationen). Als ersten Schritt musst du dieses Geheimnis widerrufen und/oder rotieren. Sobald der Schlüssel widerrufen oder rotiert wurde, kann er nicht mehr für den Zugriff verwendet werden, und das könnte ausreichen, um Ihr Problem zu lösen. Das Durchlaufen der zusätzlichen Schritte, um die Historie neu zu schreiben und das Geheimnis zu entfernen, ist möglicherweise nicht erforderlich.
Nebenwirkungen des Neuschreibens der Geschichte
Es gibt zahlreiche Nebenwirkungen beim Umschreiben der Geschichte. Diese schließen Folgendes ein:
-
**Hohes Risiko einer erneuten Kontamination**: Es ist bedauerlicherweise einfach, die vertraulichen Daten erneut in das Repository zu pushen und mehr Schaden anzurichten. Wenn ein anderer Entwickler einen Klon von vor der Änderung hat und nach der Änderung einfach `git pull` gefolgt von `git push` ausführt, werden die vertraulichen Daten zurückgegeben. Dieser muss entweder seinen Klon verwerfen und erneut klonen oder sorgfältig mehrere Schritte durchlaufen, um den Klon zuerst zu bereinigen. -
**Risiko des Verlusts der Arbeit anderer Entwickler**: Wenn andere Entwickler während der Bereinigungsversuche weiterhin Branches aktualisieren, die die vertraulichen Daten enthalten, musst du die Bereinigung wiederholen oder ihre Arbeit verwerfen. -
**Geänderte Commithashes**: Das Neuschreiben der Historie wird die Hashes der Commits, die die vertraulichen Daten eingeführt haben, _und_ alle nachfolgenden Commits ändern. Alle Tools oder Automatisierungen, die darauf angewiesen sind, dass sich Commit-Hashes nicht ändern, werden nicht funktionieren oder auf Probleme stoßen. -
**Herausforderungen beim Branchschutz**: Wenn du Branchschutzmaßnahmen hast, die erzwungene Pushes verhindern, müssen diese Schutzmaßnahmen (zumindest vorübergehend) deaktiviert werden, damit die vertraulichen Daten entfernt werden. -
**Fehlerhafte Vergleichsansicht für geschlossene Pull-Anforderungen**: Das Entfernen der vertraulichen Daten macht es erforderlich, die internen Verweise zu entfernen, die zum Anzeigen der Vergleichsansicht in Pull_Anforderungen verwendet werden. Dadurch werden diese Vergleiche nicht mehr angezeigt. Das gilt nicht nur für den Pull Request, der die vertraulichen Daten eingeführt hat, sondern für jeden Pull Request, der auf einer Version des Verlaufs nach dem Mergen der vertraulichen Daten basiert, selbst wenn diese späteren Pull Requests keine Datei mit vertraulichen Daten hinzugefügt oder geändert haben. -
**Schlechte Interaktion mit offenen Pull Requests**: Geänderte Commit-SHAs führen zu einem anderen Pull-Request-Diff, und Kommentare zum alten Pull-Request-Diff können ihre Gültigkeit verlieren und verloren gehen, was zu Verwirrung bei Erstellern und Reviewern führen kann. Wir empfehlen, alle geöffneten Pull Requests zusammenzuführen oder zu schließen, bevor du Dateien aus deinem Repository entfernst. -
**Verlorene Signaturen bei Commits und Tags**: Signaturen für Commits oder Tags hängen von Commithashes ab. Da Commithashes durch das erneute Generieren des Verlaufs geändert werden, sind Signaturen nicht mehr gültig, und die Signaturen werden durch viele Tools zum erneuten Generieren des Verlaufs (einschließlich `git-filter-repo`) einfach entfernt. Tatsächlich entfernt `git-filter-repo` auch die Commit-Signaturen und Tag-Signaturen von Commits, die vor dem Entfernen der vertraulichen Daten erstellt wurden. (Eigentlich kann dies mit der Option `--refs` umgangen werden, um bei Bedarf `git-filter-repo` anzuwenden. Es muss jedoch sichergestellt werden, dass alle Verweise angegeben werden, die vertrauliche Daten in ihrem Verlauf haben und die Commits enthalten, die die vertraulichen Daten in deinem Bereich eingeführt haben). -
**Direkte Führung anderer zu vertraulichen Daten**: Git wurde mit kryptografischen Überprüfungen entwickelt, die in Commit-Identifizierer integriert sind, damit Angreifer nicht auf einen Server zugreifen und den Verlauf ändern können, ohne dass dies bemerkt wird. Das ist aus Sicherheitsperspektive hilfreich, aus der Perspektive vertraulicher Daten bedeutet das jedoch, dass das Löschen vertraulicher Daten einen aufwändigen Prozess der Koordination erfordert. Zudem bedeutet es, dass bei Änderungen des Verlaufs informierte Benutzer mit einem vorhandenen Klon die Divergenz im Verlauf bemerken und diese nutzen können, um die sensiblen Daten, die du aus dem zentralen Repository entfernt hast, dennoch schnell und einfach in ihrem Klon zu finden.
Informationen zur Offenlegung vertraulicher Daten
Das Entfernen vertraulicher Daten aus einem Repository umfasst vier allgemeine Schritte:
- Lokales Umschreiben des Repositorys mit git-filter-repo
- Aktualisieren Sie das Repository auf GitHub, indem Sie Ihre lokal umgeschriebene Historie verwenden.
- Koordination mit Kollegen zum Bereinigen weiterer vorhandener Klone
- Verhindern von Wiederholungen und Vermeiden zukünftiger Lecks vertraulicher Daten
Wenn Sie Ihren Verlauf lediglich neu schreiben und einen Push erzwingen, können die Commits mit vertraulichen Daten möglicherweise noch an anderer Stelle zugänglich sein.
- In allen Klonen oder Forks Ihres Repositorys
- Direkt über ihre SHA-1-Hashes in zwischengespeicherten Ansichten auf GitHub
- Durch beliebige Pull Requests, die darauf verweisen
Du kannst vertrauliche Daten nicht aus den Klonen anderer Benutzer von deinem Repository entfernen. Stattdessen musst du ihnen die Anweisungen aus dem Kapitel Stelle sicher, dass andere Kopien bereinigt werden: Klone von Kollegen im git-filter-repo-Leitfaden senden, damit sie es selbst tun. Du kannst jedoch zwischengespeicherte Ansichten und Verweise auf die vertraulichen Daten in Pull Requests für GitHub dauerhaft entfernen, indem du uns über das GitHub-Support-Portal kontaktierst.
Wichtig
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 Ändern der betroffenen Anmeldeinformationen verringert werden kann.
Wenn der Commit, der die vertraulichen Daten eingeführt hat, in allen Forks vorhanden ist, kann weiterhin darauf zugegriffen werden. Sie müssen sich mit den Besitzern der Forks abstimmen und sie bitten, die vertraulichen Daten zu entfernen oder die Verzweigung vollständig zu löschen. GitHub können keine Kontaktinformationen für diese Besitzer bereitstellen.
Berücksichtigen Sie diese Einschränkungen und Herausforderungen bei Ihrer Entscheidung, den Verlauf Ihres Repositorys neu zu schreiben.
Löschen einer Datei aus dem Verlauf eines lokalen Repositorys mithilfe von git-filter-repo
-
Installiere das neueste Release des
git-filter-repo-Tools. Du benötigst eine Version mit dem--sensitive-data-removal-Flag, also mindestens Version 2.47. Du kannstgit-filter-repomanuell oder mithilfe eines Paket-Managers installieren. Verwenden Sie beispielsweise den Befehlbrew install, um das Tool mit HomeBrew zu installieren.brew install git-filter-repoWeitere Informationen findest du in INSTALL.md im Repository
newren/git-filter-repo. -
Klone das Repository auf deinen lokalen Computer. Weitere Informationen findest du unter Ein Repository klonen.
git clone https://github.com/YOUR-USERNAME/YOUR-REPOSITORY -
Navigiere zum Arbeitsverzeichnis des Repositorys.
cd YOUR-REPOSITORY -
Führen Sie einen
git-filter-repo-Befehl aus, um die vertraulichen Daten zu bereinigen.Wenn du eine bestimmte Datei aus allen Branches/Tags/Verweise löschen möchtest, führe den folgenden Befehl aus, indem du
PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATAdurch den Git-Pfad zur Datei ersetzt, die du entfernen möchtest, nicht nur den Dateinamen (z. B.src/module/phone-numbers.txt):git-filter-repo --sensitive-data-removal --invert-paths --path PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATAWichtig
Wenn die Datei mit vertraulichen Daten in anderen Pfaden vorhanden ist (da sie verschoben oder umbenannt wurde), musst du entweder ein zusätzliches
--path-Argument für diese Datei hinzufügen oder diesen Befehl ein zweites Mal ausführen, um den alternativen Pfad zu benennen.Wenn du den gesamten Text ersetzen möchtest, der in
../passwords.txtaus nicht-binären Dateien im Verlauf deines Repositorys gefunden wurde, führe den folgenden Befehl aus:git-filter-repo --sensitive-data-removal --replace-text ../passwords.txt -
Stelle sicher, dass du alles, was du aus dem Repository-Verlauf entfernen wolltest, tatsächlich entfernt hast.
-
Finde heraus, wie viele Pull Requests durch das Umschreiben der Historie beeinträchtigt werden. Du benötigst diese Informationen unten.
$ grep -c '^refs/pull/.*/head$' .git/filter-repo/changed-refs 4Du kannst
-cweglassen, um zu sehen, welche Pull Requests betroffen sind:$ grep '^refs/pull/.*/head$' .git/filter-repo/changed-refs refs/pull/589/head refs/pull/602/head refs/pull/604/head refs/pull/605/headDiese Ausgabe enthält die Pull-Request-Nummer zwischen dem zweiten und dritten Schrägstrich. Wenn die Anzahl der betroffenen Pull Requests größer ist als erwartet, kannst du diesen Klon ohne Nachteile verwerfen und entweder das Neugenerieren wiederholen oder das Entfernen vertraulicher Daten abbrechen. Sobald du mit dem nächsten Schritt fortfährst, wird die Umschreibung unumkehrbar.
-
Sobald du mit dem Status deines Repositorys zufrieden bist, führe einen erzwungenen Push deiner lokalen Änderungen durch, um dein Repository auf GitHub.com zu überschreiben. Obwohl
--forcedurch--mirrorimpliziert wird, fügen wir es unten als Erinnerung ein, dass du zwangsweise alle Branches, Tags und Refs aktualisierst und dabei alle Änderungen verwerfen wirst, die andere möglicherweise an diesen Refs vorgenommen haben, während du das Repository bereinigt hast.git push --force --mirror originDer Befehl schlägt fehl, wenn er versucht, Verweise zu pushen, die mit
refs/pull/beginnen, da GitHub diese als schreibgeschützt kennzeichnet. Diese Pushfehler werden im nächsten Abschnitt behandelt. Wenn ein anderer Verweis nicht gepusht wird, haben Sie den Schutz für diese Verzweigung vermutlich aktiviert. Sie müssen ihn vorübergehend deaktivieren und den Push wiederholen. Wiederholen Sie den Vorgang, bis nur noch Aktualisierungsfehler bei Referenzen auftreten, die mitrefs/pull/beginnen.
Vollständiges Entfernen der Daten aus GitHub
Nachdem du git-filter-repo verwendet hast, um die vertraulichen Daten zu entfernen und deine Änderungen an GitHub zu pushen, musst du einige weitere Schritte ausführen, um die Daten vollständig aus GitHub zu entfernen.
-
Wende dich an uns über das GitHub-Support-Portal, und gib die folgenden Informationen an:
- Name des Besitzers und des betroffenen Repositorys (z. B. DEIN-BENUTZERNAME/DEIN-REPOSITORY)
- Die Anzahl der betroffenen Pull Requests, die im vorherigen Schritt gefunden wurden. Dies wird vom Support verwendet, um zu überprüfen, ob Sie verstehen, wie stark die Auswirkungen sein werden.
- Der bzw. die von
git-filter-repogemeldete(n) erste(n) geänderte(n) Commit(s) (Suche in der Ausgabe nachNOTE: First Changed Commit(s).) - Wenn
NOTE: There were LFS Objects Orphaned by this rewritein der git-filter-repo-Ausgabe (direkt nach dem ersten geänderten Commit) angezeigt wird, merke an, dass verwaiste LFS-Objekte vorhanden sind, und lade die benannte Datei ebenfalls in das Ticket hoch.
Wenn du alle Verweise mit Ausnahme von PRs erfolgreich bereinigt hast und keine Forks Verweise auf die vertraulichen Daten enthalten, wird der Support folgendermaßen handeln:
-
Dereferenzieren oder Löschen betroffener PRs auf GitHub
-
Ausführen einer Garbage Collection auf dem Server, um die vertraulichen Daten aus dem Speicher zu löschen
-
Entfernen zwischengespeicherter Ansichten
-
Wenn LFS-Objekte involviert sind: Löschen und/oder bereinigen Sie die verwaisten LFS-Objekte
Wichtig
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 das Rotieren betroffener Anmeldeinformationen verringert werden kann.
-
Mitwirkende müssen ein Rebase, und kein Merge, für Verzweigungen durchführen, die sie aus deinem alten (nicht mehr gültigen) Repositoryverlauf erstellt haben. 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. Sie müssen möglicherweise auch zusätzliche Schritte unternehmen. Weitere Informationen finden Sie unter Stellen Sie sicher, dass andere Kopien bereinigt werden: Klone von Kollegen im
git-filter-repo-Leitfaden.
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.
Es gibt einige Maßnahmen, mit denen vermieden werden kann, dass für Dinge Commits oder Push-Vorgänge durchgeführt werden, die nicht offengelegt werden sollten:
- Wenn es wahrscheinlich ist, dass die vertraulichen Daten in einer Datei gefunden werden, die nicht von Git nachverfolgt werden soll, füge die entsprechenden Dateinamen zu
.gitignorehinzu, und stelle sicher, dass du diese Änderung an.gitignorepushst, damit weitere Entwickler geschützt sind. - Vermeide die Hartcodierung vertraulicher Informationen im Code. Verwenden Sie Umgebungsvariablen oder Geheimverwaltungsdienste wie Azure Key Vault, AWS Secrets Manager oder HashiCorp Vault, um geheime Schlüssel zur Laufzeit zu verwalten und einzugeben.
- Erstelle einen Hook vor dem Commit, um nach vertraulichen Daten zu suchen, bevor diese an beliebiger Stelle committet oder gepusht werden, oder verwende in einem Hook vor dem Commit ein bekanntes Tool wie git-secrets oder gitleaks. (Fordern Sie alle Mitwirkenden auf, den von Ihnen ausgewählten Hook vor dem Commit einzurichten.)
- 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 .undgit commit -ain der Befehlszeile – verwende stattdessengit add filenameundgit rm filename, um die Dateien einzeln zu stagen. - 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, dengit commiterzeugt, solange du nicht das-aFlag verwendest. - Aktivieren Sie Push-Schutz für Ihr Repository, um zu erkennen und zu verhindern, dass Push-Vorgänge mit hardcodierten Geheimnissen in Ihre Codebasis übernommen werden. Weitere Informationen finden Sie unter Informationen zum Pushschutz.
Weiterführende Lektüre
-
[ `git-filter-repo` Hauptseite](https://htmlpreview.github.io/?https://github.com/newren/git-filter-repo/blob/docs/html/git-filter-repo.html), insbesondere der Unterabschnitt „Entfernen vertraulicher Daten“ des Abschnitts „DISKUSSION“. -
[Pro Git: Git-Tools – Umschreiben der Historie](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History) -
[AUTOTITLE](/code-security/secret-scanning/introduction/about-secret-scanning)