Blog
Der Nutzen oder die Nutzlosigkeit von signierten Commits

Jede Übertragung, die Sie vornehmen, speichert den Namen und die E-Mail-Adresse, die Sie in Ihrer Git-Konfiguration angegeben haben. Aber Git prüft nicht, ob Sie das sind. Selbst Sie können problemlos einen Commit mit dem Namen und der E-Mail-Adresse eines beliebigen berühmten Programmierers erstellen, und Ihr Git Repo wird dies akzeptieren.
Aus diesem Grund ist es möglich, einen Commit zu signieren. Das Signieren eines Commits fügt einen kryptografischen Beweis Ihrer Identität hinzu, indem es einen öffentlichen/privaten Schlüssel verifiziert. Commits können mit GPG, SSH oder S/MIME von Ihrem Arbeitsplatz aus signiert werden, und GitHub kann Commits, die Sie im Web vornehmen, "in Ihrem Namen" signieren (d.h. mit dem eigenen Schlüssel von GitHub).
Ich werde GitHub als Beispiel für eine Hosting-Plattform für Ihre Git-Repositorys verwenden, aber konzeptionell gilt dies für Git im Allgemeinen und alle anderen Git-Hosting-Plattformen.
Um Ihre Identität auf GitHub zu verifizieren, müssen Sie Ihre Schlüssel hochladen, damit überprüft werden kann, ob Sie derjenige sind, der Sie sind. Wenn Sie das richtig gemacht haben, sehen Sie ein kleines Abzeichen (verifiziert) neben einem Commit, der auf diese Weise signiert ist.
Die kryptografische Signatur ist Teil des Commits. Wenn also ein Repository von einem Rechner auf einen anderen oder von einem Hosting-Anbieter auf einen anderen übertragen wird, sollten Sie immer noch in der Lage sein, zu überprüfen, ob das Repository "intakt" ist, wenn Sie eine Kopie aller öffentlichen Schlüssel der Mitwirkenden haben. Aus diesem Grund funktioniert die Commit-Signierung unabhängig vom Host des Repositorys. Das ist auch der Grund, warum es so schwer ist, es richtig zu machen.
"Großartig!" werden Sie vielleicht sagen. Und viele Experten werden dies im Internet, in Konferenzvorträgen und Büchern bestätigen, darunter auch einige meiner eigenen Kollegen. Aber wenn Sie sich diese Blogs durchlesen, werden Sie sofort sehen, dass es nicht einfach ist, sie einzurichten.
Signieren von Git Commits mit YubiKey unter Windows
Es gibt mehrere Dinge, die wir tun müssen, um eine durchgängige Sicherheit in unserer Version zu erreichen...
So richten Sie signierte Git Commits mit einem YubiKey NEO und GPG und Keybase unter Windows ein
Diese Woche bringe ich Ihnen in obskuren Blogtiteln den Alptraum, den die Einrichtung...
Erhöhen Sie Ihre Git-Sicherheit: Signieren von GitHub Commits mit 1Password in Windows WSL und Containern
Dies ist eine Schritt-für-Schritt-Anleitung zur Einrichtung des 1Password SSH-Agenten, der Ihnen ssh-Authentifizierungs- und Signierschlüssel zur Verfügung stellt, um einen reibungslosen Git-Workflow in WSL und VSCode DevContainern zu ermöglichen.
Und, ja, es ist großartig... In gewisser Weise. Und es ist auch nicht großartig. Lassen Sie mich das erklären.
Was bedeutet das (verifizierte) Abzeichen?
Ein Commit, das das (verifizierte) Abzeichen zeigt, sagt Ihnen Folgendes:
✅ Der Commit wurde signiert ✅ Die Signatur ist korrekt ✅ Die Signatur stimmt mit der im Commit verwendeten E-Mail überein ✅ Der zum Signieren verwendete Schlüssel ist GitHub bekannt ✅ Der Schlüssel und die E-Mail gehören dem angegebenen Konto (in diesem Fall octocat) ✅ Ob der Inhalt des Commits (noch) mit der Signatur übereinstimmt ✅ Möglicherweise: Dass der Schlüssel einer Organisation oder einem Unternehmen gehört/abgeleitet/vertrauenswürdig ist. ✅ Der Commit wurde wahrscheinlich von der Person durchgeführt, von der Sie glauben, dass sie den Commit durchgeführt hat
Großartig!
Was bedeutet das (verifizierte) Abzeichen nicht?
Ein Commit, das das (verifizierte) Abzeichen anzeigt, sagt Ihnen nicht das Folgende:
⛔ Ob der Unterzeichner den Inhalt des Commits überprüft und genehmigt hat ⛔ Ob der Inhalt des Commits zwischen dem Staging und dem Commit verändert wurde ⛔ Ob der Unterzeichner den Commit persönlich durchgeführt hat (oder eine Automatisierung in seinem Namen unterschreiben ließ) ⛔ Ob das Konto kompromittiert ist oder nicht ⛔ Ob der Kontoinhaber seinen privaten Schlüssel sicher aufbewahrt hat ⛔ Ob das Konto tatsächlich das Konto ist, das Sie erwartet haben. Dies kann für Sie schwer zu unterscheiden sein. Ist es Octocat oder 0ctocat? ⛔ Ob das Konto immer noch der gleichen Person gehört, als Sie das letzte Mal auf das Profil gestoßen sind (es könnte gestohlen worden sein)
Im Grunde genommen: Ob der Commit tatsächlich von der Person durchgeführt wurde, von der Sie glauben, dass sie den Commit durchgeführt hat
Das (verifizierte) Abzeichen ist also weder ein Gütesiegel noch ein universelles Signal des Vertrauens.
Was bedeutet das (ungeprüfte) Abzeichen?
Bleibt noch das (ungeprüfte) Abzeichen. Das ist vielleicht das nützlichste Signal, das die Commit-Signierung geben kann. Es signalisiert, dass:
✅ Die Übertragung wurde mit einem Schlüssel signiert, der nicht zu dem Konto gehört, das die Übertragung vorgenommen hat. ✅ Die Übertragung wurde mit einem Schlüssel signiert, der nicht zu einer bekannten E-Mail des Kontos passt, das die Übertragung vorgenommen hat. ✅ Sie können nicht darauf vertrauen, dass die Übertragung von der Person vorgenommen wurde, von der Sie annehmen, dass sie die Übertragung vorgenommen hat.
Wie kann das alles schief gehen?
Generierung und Speicherung Ihrer Schlüssel
Um die Commit-Signierung korrekt durchzuführen, müssen Benutzer mehrere Schritte unternehmen.
- Sie müssen ein Schlüsselpaar erwerben.
- Die meisten Leute werden einen ssh-Schlüssel oder einen GPG-Schlüssel auf ihrem Rechner erzeugen.
- Einige Unternehmen erstellen einen Schlüssel für Sie und händigen ihn Ihnen aus.
- Sie müssen die privaten Schlüssel auf irgendeine Weise schützen
- Verschlüsseln Sie sie mit einer Passphrase
- Schützen Sie sie mit einem 2FA-Token (wie einem YubiKey)
- Legen Sie die Berechtigungen für das Dateisystem fest
- Speichern Sie sie in einem Software-Schlüsseltresor (zum Beispiel: Windows Credential Manager oder 1Password)
- Oder setzen Sie sie auf eine Smartcard
- Sichern Sie den Schlüssel an einem sicheren Ort
- Löschen Sie den ungeschützten Schlüssel gründlich
- Sie müssen den privaten Schlüssel auf jedem Gerät, jeder VM, jedem Container und jedem Benutzerprofil hinterlegen, das Sie zum Signieren von Commits verwenden möchten. (Oder Sie generieren für jedes Gerät einen neuen Schlüssel, aber woher sollen die Leute dann wissen, dass sie Ihren Schlüsseln vertrauen sollen?).
- Sie müssen Ihre Schlüssel auf GitHub und andere Plattformen hochladen, auf denen Ihre Identität bekannt werden soll.
- Sie müssen sicherstellen, dass Ihre Schlüssel die meiste Zeit "gesperrt" sind, um zu verhindern, dass Malware auf Ihrem Rechner den Schlüssel während der Entwicklung abfängt.
Wenn Sie nach Anleitungen zum Signieren Ihrer Commits suchen, finden Sie die allgemeinen Anweisungen zum Generieren des Schlüssels und zum Einrichten von Git für die Verwendung des Schlüssels, aber diese sagen Ihnen in der Regel nicht, wie Sie den privaten Schlüssel sicher aufbewahren und wie Sie sicherstellen, dass er die meiste Zeit gesperrt ist.
Ich habe schon viele Leute gesehen, die ihr Schlüsselmaterial im Home-Verzeichnis ihres Benutzers gespeichert haben, ohne eine Passphrase. Ich selbst habe diesen Fehler mindestens einmal in meiner Karriere gemacht.
Das ist großartig, denn sie machen das Signieren von Verpflichtungen einfach. So wie Let's Encrypt es für jeden einfach gemacht hat, seine Website zu sichern.
Natürlich könnte die Schlüsselgenerierung und -verteilung von Ihrer IT-Abteilung übernommen werden. Und diese könnte Ihnen an Ihrem ersten Arbeitstag 2 Yubikeys überreichen. Leider gibt es für die überwiegende Mehrheit der Betreuer und Mitwirkenden keine IT-Abteilung, die sich um all die kleinen und großen Details kümmert.
Oder wenn Sie einen Beitrag zum Linux-Kernel leisten und Ihren Patch per E-Mail mit einer signierten Patch-Datei einreichen, ist dies die einzige Möglichkeit, Ihre Arbeit in das Repository zu integrieren:
Einreichen von Patches: Der Leitfaden für die Aufnahme Ihres Codes in den Kernel - Die Linux-Kernel-Dokumentation
Überprüfen der Identität eines Commit-Autors
Das Problem der Verteilung Ihrer Schlüssel an Ihre Kollegen ist damit immer noch nicht gelöst. Ihr Commit wird zwar auf GitHub angezeigt (verifiziert), aber Sie können die Signatur eines Commits auf Ihrem lokalen Rechner, dem Build-Agent oder im Repo eines anderen Anbieters wie GitLab nicht verifizieren. Im Gegensatz zu den Browsern, auf denen vertrauenswürdige Root-Zertifikate vorinstalliert sind, verfügen der Git-Client und die Hosts nicht über ein eingebautes System zum Austausch öffentlicher Schlüssel.
Um also echten Schutz zu bieten, nicht nur auf GitHub, benötigen Sie:
- Eine Möglichkeit, Ihren öffentlichen Schlüssel zu verbreiten.
- Einen Schlüssel widerrufen können
- Einen Schlüssel drehen können
- Eine Möglichkeit, die Schlüssel der Menschen zu erhalten, mit denen Sie arbeiten
In einer Unternehmensumgebung kann Ihre IT- oder Sicherheitsabteilung dies vielleicht für Sie einrichten, aber für die meisten Mitarbeiter in der Welt ist dies etwas, das sie selbst tun müssen. Und viele haben keine Ahnung, wie man das richtig macht.
Was die Sache noch schwieriger macht, ist die Tatsache, dass die Identität nur schwer zu überprüfen ist. Viele Menschen verwenden eine E-Mail-Adresse von gmail.com oder outlook.com. Es wäre also trivial, eine E-Mail-Adresse zu erstellen, die ähnlich, aber anders ist. Ich habe zum Beispiel eine: jesse.houwing@gmail.com, aber nichts hindert Sie daran, jhouwing@gmail.com oder jesse.h0uwing@gmail.com oder jesse.houw1ng@gmail.com zu erstellen, einen Schlüssel dafür zu generieren und diesen bei GitHub zu registrieren. GitHub zeigt (verifiziert) im Commit an und es liegt an Ihnen, die Identität des zugrunde liegenden Benutzers zu überprüfen.
Das Gleiche gilt für GitHub-Profile. Es ist nicht schwer, ein neues Konto zu erstellen, eine Reihe von Repos zu spiegeln und dann einen Pull Request zu erstellen, der auf den ersten Blick authentisch aussieht. Ein weiteres Problem ist die Tatsache, dass ein GitHub-Konto, wenn es umbenannt oder gelöscht wird, nach 90 Tagen für neue Benutzer verfügbar wird. So kann octocat von der exzellenten Pull-Anfrage des letzten Jahres heute jemand ganz anderes sein als octocat. Da der neue Besitzer des Kontos neues Schlüsselmaterial hinzufügen kann, wird jeder Commit, den er macht, als (verifiziert) angezeigt. Nicht jeder Repo-Hoster verhindert derzeit, dass Sie sehr ähnliche Benutzernamen erstellen oder warnt seine Benutzer, dass ein sehr ähnlicher Benutzername erstellt wurde. GitHub schlägt sogar vor, den gewünschten Benutzernamen leicht zu ändern, wenn das gewünschte Konto bereits vergeben ist, und hindert Sie nicht daran, ein Konto zu erstellen, das einem bestehenden Konto sehr ähnlich sieht.
Und dann gibt es noch ein weiteres Problem: die Privatsphäre. GitHub und andere Plattformen ermöglichen es Benutzern, ihre wahre E-Mail-Adresse geheim zu halten. Stattdessen verwendet GitHub für Ihre Commits eine Adresse in folgendem Format: ID+USERNAME@users.noreply.github.com. Benutzer, die sich für diese Datenschutzfunktion entscheiden, sind noch schwieriger zu verifizieren, da Sie ihre wahre E-Mail-Adresse nicht sehen können.
Validierung des Inhalts einer Übertragung
Selbst wenn der Commit von der richtigen Person signiert wurde, gibt es keine Garantie dafür, dass der Inhalt des Commits auch von dieser Person geschrieben wurde. Wenn Sie Ihrem Repository neuen Code hinzufügen möchten, müssen Sie ein paar Schritte durchlaufen:
# change a set of files
echo "// small change" >> thefile.cs
# stage the changes
git add thefile.cs
# commit & sign
git commit -m "committing my stuff" -s
# push the commit to the remote
git push origin main
Das Problem ist, dass sich Malware zwischen diesen Schritten einschleusen könnte. Ein sorgfältiger Mitarbeiter würde also git status ausführen und ein diff machen, um den Inhalt des Staging-Bereichs und die Ergebnisse des Commits zu überprüfen, bevor er das Projekt veröffentlicht. Ein etwas paranoiderer Maintainer wird seine SSH-Passphrase eingeben müssen, um den Push zu initiieren. Aber seien wir mal ehrlich: die meisten von uns tun das nicht.
Ein Pre-Commit-Hook, ein Git-Filter oder ein im Hintergrund laufendes Programm könnte den Inhalt der Datei zwischen Git-Add und Git-Commit ändern, ohne dass die meisten Mitwirkenden davon etwas mitbekommen würden. Oder es könnte Ihre Passphrase für Ihren privaten Schlüssel abfangen und von Ihrem Rechner exfiltrieren.
Aber wahrscheinlich noch einfacher ist es, wenn sich ein bösartiges npm-Paket auf Ihren Rechner geschlichen hat und sich im package-lock.json eingenistet hat, für das die meisten Diffs ohnehin standardmäßig versteckt sind:
Hoffentlich werden diese Änderungen am Code während des Pull Request oder von einem Tool, das den Pull Request überprüft, entdeckt. Es wäre nicht das erste Mal, dass solche Änderungen unentdeckt bleiben. Leider zeigen Ihnen nur sehr wenige IDEs und Git-Clients die Inhalte an, die Sie gerade signieren oder die Sie gerade signiert haben. Und selbst wenn dies der Fall wäre, ist es unwahrscheinlich, dass Sie beim Übertragen einer großen Änderung an einer Datei einen Code bemerken, der 600 Tabs nach rechts eingerückt oder angehängt wurde.
Und wenn ein Mitwirkender sein Schlüsselmaterial nicht ordnungsgemäß geschützt hat, wäre es für einen Angreifer sogar noch trivialer, den Schlüssel zu nehmen und ihn irgendwo hin zu schicken, um ihn zu einem beliebigen späteren Zeitpunkt zu verwenden, ohne dass Sie es je bemerken.
Selbst wenn ein Benutzer eine Passphrase oder eine 2-Faktor-Authentifizierung eingerichtet hat, kann es sein, dass er seinen YubiKey einfach in seinem USB-Anschluss lässt und ihn bei jeder Aufforderung antippt. Wenn ein Benutzer nicht genau weiß, wann er eine Eingabeaufforderung zu erwarten hat, kann es sein, dass er seine Passphrase einfach in jede Eingabeaufforderung eingibt, die danach fragt.
Ein großer Teil des "sicheren" Aspekts der Commit-Signierung hängt davon ab, dass der Beitragende genau weiß, wie viele "obskure" Hilfsprogramme funktionieren und wann es sicher ist, sein Passwort in eine Eingabeaufforderung einzugeben. Ich vermute, dass es viel sicherer wäre, wenn GitHub den Benutzer über GitHub Mobile auffordern würde, wenn er einen Push erhält, als zu erwarten, dass ein Benutzer weiß, welchen Prompts er vertrauen kann.
Das (verifizierte) Abzeichen ist wie das ️, das wir aus der Browserleiste entfernt haben.
Das bringt mich zu dem Grund, warum ich diesen Artikel geschrieben habe. Derzeit sind die meisten Autoren und Betreuer, die ihre Signierinfrastruktur richtig eingerichtet haben, Power-User, die (hoffentlich) wissen, wie man das richtig macht. Aber die allgemeine Bevölkerung dazu zu drängen, die Commit-Signierung einzurichten, wird das Vertrauen, das ich in das (verifizierte) Badge habe, nur schwächen. Ich glaube nicht, dass alle GitHub-Benutzer in der Lage sein werden, ihre Umgebung richtig einzurichten oder ihre privaten Schlüssel zu schützen.
Auf seine eigene Art und Weise ist das (verifizierte) Abzeichen sehr ähnlich wie das ️-Schild, das wir früher in der URL-Leiste des Browsers angezeigt haben. Banken würden Ihnen sogar sagen, dass das Schild ein Leuchtfeuer des Vertrauens ist. Websites würden stolz ein Schild zeigen, um mit ihren Zertifikaten zu prahlen:
Bis https zum Standard wurde und jeder anfing, es zu verwenden. Bösewichte haben nun ihre Phishing-Seiten mit denselben hochwertigen SSL-Zertifikaten ausgestattet und der Wert des Schutzschilds hat sich völlig verflüchtigt. Nur wenn eine Website wirklich versucht, sich als jemand anderes auszugeben, zeigt der Browser jetzt an, dass Sie sich auf gefährliches Terrain begeben. Alle großen Browser zeigen jetzt nur noch an, wenn eine Verbindung unsafe ist.
Weiterentwicklung der Sicherheitsindikatoren von Chrome
Zuvor hatten wir einen Vorschlag veröffentlicht, alle HTTP-Seiten definitiv als "nicht sicher" zu kennzeichnen und die Sicherheitsindikatoren für HTTPS-Seiten zu entfernen. HTTPS-Seiten...
Für mich hat das (verifizierte) Abzeichen wenig Wert, aber ich sehe viel Wert in dem (unverifizierten) oder (ungültigen) Status. Diese sind ein klares Signal, dass etwas nicht stimmt. Leider wird das (verifizierte) Badge angesichts des derzeitigen Chaos bei der Einrichtung und des völligen Fehlens einer allgegenwärtigen Infrastruktur für den Austausch öffentlicher Schlüssel und die effektive Überprüfung der Identität nicht ausreichen.
Ich sage voraus, dass das (verifizierte) Abzeichen den Weg des https Schildes gehen wird. Sobald die meisten Leute verifiziert sind, werden Anbieter wie GitHub es nicht mehr als Vertrauensbeweis zeigen, sondern Sie nur noch warnen, wenn etwas nicht stimmt.
Es gibt bereits Richtlinien, die Sie in Ihrem Projektarchiv aktivieren können, um zu erzwingen, dass alle Commits signiert werden und dass alle Commits, die von github.com aus gemacht werden, signiert werden. Dadurch wird sichergestellt, dass die Commits nicht falsch oder gar nicht signiert wurden. Aber es kann nicht wirklich verifizieren, dass die Commits von Leuten gemacht wurden, denen Sie vertrauen sollten.
Warum brauchen wir das überhaupt?
Erschwerend kommt hinzu, dass Git-Hosting-Plattformen wie GitHub, Azure Repos und GitLab bereits über bessere Möglichkeiten verfügen, um festzustellen, wer Sie sind. Bevor ich einen Push zu GitHub mache, melde ich mich mit meinem GitHub-Konto an, führe SSO mit meiner Unternehmensidentität durch und gebe dabei mehrere 2. GitHub kennt meine E-Mail-Adressen, weil es sie bereits verifiziert hat. Und andere Hosting-Plattformen können bereits dasselbe tun und haben einen Speicher für die Kontoidentität aller Benutzer auf ihren Plattformen. Die derzeitige Art und Weise, mit dem Signieren von Commits umzugehen, gibt es natürlich, weil Git keine Hosting-Plattform braucht. Es ist ein verteiltes Versionskontrollsystem und wird vielleicht von Leuten verwendet, die sich nie mit GitHub oder Azure Repos oder GitLab verbinden. Aber ein großer Teil der Git-Benutzer tut dies.
Bei GitHub muss ich selbst keine Schlüssel erzeugen, um zu verifizieren, dass ich einen Commit auf GitHub veröffentlicht habe. Aber wir brauchen die gesamte Signierungsinfrastruktur, um sicherzustellen, dass Sie überprüfen können, ob ich einen Commit verfasst habe, wenn Sie ihn nicht auf GitHub ansehen. Und für mich ist das wahrscheinlich eine wichtigere Information als der Name und die E-Mail-Adresse des Commit-Autors, die er in seinem Git-Client konfiguriert hat.
Ich vermute, dass wir in Zukunft einen Git Signing Manager haben werden, der Ihre Commits mit Ihrem Authentifizierungs-Token signieren kann, ähnlich wie der Git Credential Manager, der endlich Ihre Anmeldedaten sicher auf Ihrem System speichert. GitHub macht das im Grunde schon, wenn Sie Änderungen aus GitHub Codespaces übertragen oder wenn Sie Dateien direkt im Web bearbeiten. Es würde mich nicht überraschen, wenn DNS eine zentrale Rolle bei der Verteilung öffentlicher Schlüssel spielen wird.
PGP-Schlüssel im DNS veröffentlichen
Wir werden sicherlich in einem Zustand enden, in dem jeder seine Zusagen unterschreibt, aber wir werden das nirgendwo sehen, es sei denn, es stimmt etwas nicht. Und so sollte es auch sein, wenn Sie mich fragen.
Dieser Artikel ist Teil von XPRT.#16. Laden Sie das Magazin hier herunter.
Verfasst von
Jesse Houwing
Jesse is a passionate trainer and coach, helping teams improve their productivity and quality all while trying to keep work fun. He is a Professional Scrum Trainer (PST) through Scrum.org, Microsoft Certified Trainer and GitHub Accredited Trainer. Jesse regularly blogs and you'll find him on StackOverflow, he has received the Microsoft Community Contributor Award three years in a row and has been awarded the Microsoft Most Valuable Professional award since 2015. He loves espresso and dark chocolate, travels a lot and takes photos everywhere he goes.
Unsere Ideen
Weitere Blogs
Contact




