Geheimnisse: Schluessel, Speicherung und Rotation
Warum ein Schluessel in git ein Schluessel ist, der dir nicht mehr gehoert, wovor Umgebungsvariablen wirklich schuetzen, wie Rotation vor und nach einem Leck funktioniert und die ehrliche Bilanz, wo Vorfälle tatsaechlich beginnen.
Die vorige Lektion endete bei einem Passwort. Passwörter sind die Geheimnisse, die ein Mensch eintippt; diese Lektion handelt von den Geheimnissen, die ein Programm benutzt, wenn niemand zusieht: API-Schlüssel, Datenbankpasswörter, Signaturschlüssel, Tokens für andere Dienste. Sie versagen anders als menschliche Passwörter. Niemand verwendet ein Datenbankpasswort aus Bequemlichkeit wieder, niemand vergisst es, und niemand wählt ein schwaches, weil es leichter zu tippen ist. Sie versagen, weil sie an Orte kopiert werden, die nie dafür gedacht waren, und weil sie ewig leben.
Ein Geheimnis, das in ein Repository committet wurde, ist keine Datei, die man löschen kann. Git speichert Momentaufnahmen, und jede Momentaufnahme, die den Schlüssel je enthielt, enthält ihn weiterhin. Die Zeile in einem neuen Commit zu entfernen, nimmt sie aus dem aktuellen Zustand und ändert nichts an der Historie. Selbst ein Force-Push, der den Branch neu schreibt, lässt die alten Objekte erreichbar durch das Reflog, durch jeden Fork, durch jeden bereits erstellten Klon und eine Zeit lang durch den Speicher des Anbieters selbst. Das ist kein Fehler von Git, sondern genau der Zweck einer inhaltsadressierten Historie. Das praktische Fazit ist das, dessen Annahme Teams am meisten Zeit kostet: Bis du es bemerkst, sind die Zugangsdaten als öffentlich zu behandeln. Einen abgeflossenen Schluessel in der Historie finden und bestaetigen, dass er noch erreichbar ist. Die Suche ist der leichte Teil.
$ git log --all -S 'AKIA' --oneline
9f2c1ab remove keys from config
4d7e0f3 add deployment config
$ git show 4d7e0f3:config/prod.env | grep -c AKIA
1
$ git rev-list --all --count
8421
# the commit is still reachable: history is append-onlyEinen abgeflossenen Schluessel in der Historie finden und bestaetigen, dass er noch erreichbar ist. Die Suche ist der leichte Teil.Umgebungsvariablen sind der übliche Rat, und sie sind ein Fortschritt, werden aber oft überschätzt. Was sie wirklich bringen: Das Geheimnis liegt nicht im Repository, nicht im Container-Image, und es unterscheidet sich zwischen Test und Produktion ohne Codeänderung. Was sie nicht bringen: keinerlei Isolation. Unter Linux ist die Umgebung eines laufenden Prozesses aus /proc lesbar, also kann jeder Prozess unter demselben Benutzer den Schlüssel lesen. Er landet in Absturzabbildern und in Kindprozessen, die du startest; genau so taucht ein Schlüssel des Bezahldienstes in einem Log einer unrelated Aufgabe auf. Und auf vielen Plattformen ist er im Konfigurationsbildschirm des Dashboards sichtbar, also für alle mit Deployment-Rechten. Umgebungsvariablen verschieben ein Geheimnis von einem schlechten an einen besseren Ort. Sie sind kein Tresor. Eine Umgebungsvariable kann alles lesen, was ohnehin als dieser Benutzer laufen kann. Das ist nicht nichts, aber es ist keine Geheimhaltung. Schlüsselableitung ist die Brücke vom menschlichen Geheimnis zum kryptografischen Schlüssel. Ein Passwort wird nicht direkt als AES-Schlüssel benutzt, weil Passwörter kurz und entropy-arm sind und Schlüssel gleichverteilt zufällig sein müssen. Eine Ableitungsfunktion nimmt Passwort, Salt und einen absichtlich teuren Kostenparameter und erzeugt einen Schlüssel der richtigen Länge. Dieselbe Idee erscheint an drei Stellen zugleich, und es lohnt zu sehen, dass es dieselbe Idee ist: einen Schlüssel aus einer Passphrase ableiten, einen ratresistenten Passwort-Hash ableiten und einen eigenen Schlüssel pro Datensatz aus einem Hauptschlüssel ableiten, damit ein abgeflossener Datensatzschlüssel nicht den Rest öffnet. Der Kostenparameter ist es, der jede dieser Varianten gegen einen Angreifer wappnet, der das gespeicherte Material bereits hat. Datenträgerverschlüsselung hat einen bestimmten Fehlermodus, den man benennen sollte. Liegt der Schlüssel, der die Festplatte aufschließt, auf derselben Maschine oder wird er beim Start automatisch aus einer Konfigurationsdatei geholt, dann hat jeder die Daten, der diese Maschine booten oder diese Datei lesen kann. Deshalb schützt Festplattenverschlüsselung ein gestohlenes Notebook und bringt fast nichts für einen laufenden Server, den ein Angreifer bereits erreicht hat.
in transit TLS between client and service a key you never see
at rest disk encryption, KMS envelope server holds the key
tokenized provider keeps the card number your database holds a token
PCI DSS 4.0 requires cardholder data encrypted in transit and at rest
None of the three protects against a valid account using the API.Drei Schichten, die gemeint sind, wenn es heißt, die Daten seien verschluesselt. Sie schuetzen gegen Verschiedenes, und keine schuetzt gegen eine gueltige Anfrage.Praxis
Du entdeckst, dass ein Produktions-API-Schluessel vor drei Monaten committet und im naechsten Commit entfernt wurde. Der Schluessel ist noch aktiv. Was ist die richtige erste Reaktion?
Hinweise
- Zu fragen, ob die Datei noch im Arbeitsverzeichnis liegt, ist die falsche Frage: Ein Commit behält seine eigene Kopie jeder Datei, die er je berührt hat.
- Bevor du irgendetwas neu schreibst, entscheide, ob die Zugangsdaten noch gültig sind. Wenn ja, ist das Aufräumen nicht der dringende Teil.
Bringe die Reaktion auf abgeflossene Zugangsdaten in die richtige Reihenfolge, von der ersten Handlung bis zur letzten.
- 1einen Ersatz ausgeben und bei jedem Konsumenten des alten Schlüssels ausrollen
- 2die Historie neu schreiben oder bewusst akzeptieren, dass sie bleibt, und eine Prüfung in die Pipeline aufnehmen, damit die nächste vor dem Merge auffällt
- 3die Logs nach jeder Nutzung des alten Schlüssels durchsuchen, bis zurück zum Moment des Commits
- 4aufschreiben, was passiert ist und was es früher erkannt hätte, solange die Details noch frisch sind
- 5die Zugangsdaten beim Anbieter widerrufen, damit sie sofort aufhören zu funktionieren
Hinweise
- Solange die abgeflossenen Zugangsdaten gültig sind, ist alles andere Dekoration. Der Widerruf kommt zuerst, nicht zuletzt.
- Das Repository aufzuräumen ist erst sinnvoll, wenn die Zugangsdaten nicht mehr benutzt werden können, denn die Historie neu zu schreiben ist langsam und störend.
Ordne jedem Ort, an dem ein Geheimnis leben kann, zu, wogegen er tatsaechlich schuetzt.
Hinweise
- Frage bei jeder Speichervariante, wer sie lesen kann: der Prozess selbst, jeder mit Leserecht im Dateisystem, oder nur etwas, das sich authentifiziert hat.
- Umgebungsvariablen halten Geheimnisse aus dem Repository, und das ist echter Nutzen. Vor allem, was auf derselben Maschine läuft, verbergen sie ein Geheimnis aber nicht.
Fragen zu dieser Lektion
Ist das kostenlos?
Ja. Die erste Ebene jedes Fachs ist kostenlos und braucht kein Konto. Tiefere Ebenen und die höheren Stufen sind kostenpflichtig — genau das hält das Projekt am Leben.
Für welches Alter ist das gedacht?
Für neugierige Jugendliche ab etwa 12 Jahren und für Erwachsene, die bei null anfangen. Programmiererfahrung wird nicht vorausgesetzt; die Lektionen zu Netzwerken und Physik brauchen keine Mathematik über Schulniveau.
Muss ich schon programmieren können?
Nein. Logik, Physik und Netzwerke beginnen bei null. Code schreibst du im Bereich Programmiersprachen — und auch der fängt vorne an.
Muss ich etwas installieren?
Nein. Alles läuft im Browser: Theorie, Übungen und die interaktiven Simulationen. Es gibt nichts herunterzuladen und nichts einzurichten.
Wie lange dauert ein Fach?
Eine Lektion dauert 10 bis 15 Minuten. Eine Junior-Stufe umfasst etwa 12 bis 20 Lektionen, also einige Wochen regelmäßiger Übung statt eines Abends.
Muss ich der Reihenfolge folgen?
Innerhalb einer Stufe öffnen sich die Ebenen nacheinander, weil jede auf der vorherigen aufbaut. Zwischen den Fächern bist du frei: beginne mit Logik, Physik oder Netzwerken.