GitHub-Token geleakt: Sofortmaßnahmen und Untersuchung
GitHub-PAT oder OAuth-Token geleakt? Widerrufen, hashed_token im Audit-Log finden, neue IPs, Länder und Klone prüfen und klären, worauf das Token zugriff.
Kurz gesagt. Gehen Sie davon aus, dass das Token benutzt wurde, bis die Logs das Gegenteil zeigen. Widerrufen Sie es (jeder, der den Klartextwert kennt, kann das über die API zum Widerruf von Zugangsdaten tun). Hashen Sie es (echo -n TOKEN | openssl dgst -sha256 -binary | base64) und suchen Sie im Audit-Log nach hashed_token:"…". Exportieren Sie dann die Git-Events, die bei Suchen über UI und API fehlen. Achten Sie auf neue Länder und IP-Adressen, Klon-Häufungen und alles, was das Token angelegt hat: Schlüssel, Workflows, Apps, Runner. Prüfen Sie zum Schluss den Rechner des Inhabers auf einen Infostealer.
Personal Access Tokens sind die Zugangsdaten, die Angreifer am häufigsten gegen GitHub wiederverwenden. Ein ghp_… eines Entwicklers in einer .env-Datei, einem CI-Protokoll, einer eingefügten Shell-History oder einem Infostealer-Dump verschafft einem Angreifer den Zugriff dieses Entwicklers auf jede Organisation, für die das Token autorisiert ist – ohne Passwort und ohne 2FA-Abfrage. Dieses Playbook behandelt die Untersuchung, nicht nur die Rotation.
Die erste Stunde: eindämmen, ohne Beweise zu vernichten
- Erst exportieren, dann widerrufen, wenn beides innerhalb von Minuten möglich ist. Der Widerruf wird selbst protokolliert und vernichtet daher nichts. Doch sobald das Token tot ist, weicht der Angreifer womöglich auf die Persistenz aus, die er eingerichtet hat, und Sie wollen das Bild „davor“ haben. Wird das Token gerade aktiv missbraucht, widerrufen Sie sofort.
- Widerrufen. Der Inhaber des Tokens kann es unter Settings → Developer settings → Personal access tokens löschen. Mit dem Klartextwert kann jeder den Widerrufs-Endpunkt aufrufen; er deckt klassische und Fine-grained PATs, Tokens von OAuth-Apps und User-Tokens von GitHub Apps ab. In Organisationen mit SAML-SSO kann ein Owner zusätzlich die SSO-Autorisierung des Tokens widerrufen.
- Gehen Sie davon aus, dass die Quelle weiterhin kompromittiert ist. Stammt das Token von einem Entwickler-Arbeitsplatz, hat ein Infostealer vermutlich auch Browser-Cookies, SSH-Schlüssel und Zugangsdaten der Cloud-CLIs mitgenommen. Neu aufsetzen kommt vor neu ausstellen.
Manche Tokens widerruft GitHub bereits für Sie. Laut der Dokumentation zum Widerruf von Tokens wird ein gültiges OAuth-, GitHub-App- oder Personal Access Token, das in ein öffentliches Repository oder einen öffentlichen Gist gepusht wurde, automatisch widerrufen. Dasselbe gilt für OAuth- und Personal Access Tokens, die ein Jahr lang nicht benutzt wurden. Für ein Token, das in einem privaten Repository, einem Build-Protokoll oder auf einer Paste-Website geleakt ist, übernimmt das niemand.
Das Token im Audit-Log finden
Per Token authentifizierte Ereignisse enthalten drei Felder, die unter Identifying audit log events performed by an access token dokumentiert sind:
| Feld | Bedeutung |
|---|---|
hashed_token | Base64-kodierter SHA-256-Hash des Token-Werts |
programmatic_access_type | z. B. „Personal access token (classic)“, „Fine-grained personal access token“, OAuth, GitHub App |
token_scopes | Scopes eines klassischen Tokens, z. B. repo, workflow, read:org |
Berechnen Sie den Hash des geleakten Werts und suchen Sie danach:
echo -n "$LEAKED_TOKEN" | openssl dgst -sha256 -binary | base64
# then, in the audit log search box:
# hashed_token:"Xkr8WMW4...="
Zwei Einschränkungen. Suchen über UI und REST schließen Git-Events aus; Sie müssen diese also exportieren, um Klonvorgänge mit dem Token zu sehen. Und wenn Sie den Wert nicht haben (sondern nur einen Verdacht), gehen Sie umgekehrt vor. Unter Enterprise Cloud listet der Export des Credential-Inventars hashed_token-Werte mit ihren Inhabern auf (außer bei Fine-grained PATs). So können Sie einen unbekannten Hash aus dem Log einer Person zuordnen. Der Glossareintrag zu Hashed Token bietet weitere Details.
Hat jemand anderes das Token benutzt?
Ein gestohlenes Token wird parallel zu seinem legitimen Inhaber verwendet. Sie vergleichen das Token also mit sich selbst:
- Neues Land für das Token. Die Regel
token-new-countrydes Analyzers (hoch) schlägt an, wenn einhashed_tokenaus einem Land auftaucht, das für dieses Token nie gesehen wurde – sobald der Export mindestens 24 Stunden seiner Vorgeschichte enthält. Wiederverwendung über einen VPS im Ausland passt genau in dieses Muster. - Neue IP-Adresse für das Token.
token-new-ip(niedrig) ist für sich allein laut, weil Laptops zwischen Netzen wechseln. Relevant wird die Regel, wenn sie ein Token mit einem anderen Befund teilt. - Wechsel des User-Agents. Das
git/2.39.5 (Apple Git-154)eines Entwicklers taucht plötzlich zusammen mitcurl/8.5.0oderpython-requestsbeim selben Hash auf. - Tageszeit. Aktivität um 02:00 Uhr in der Zeitzone des Inhabers, mehrere Tage hintereinander, verdient eine Nachfrage.
- Volumen. Eine Häufung von
git.cloneüber viele Repositories (siehe Repository-Exfiltration).
Diese Erkennungen brauchen actor_ip und Länderdaten. Enthält der Export keine IP-Adressen, aktivieren Sie die Anzeige der IP-Adressen, die auch für bestehende Ereignisse gilt, und exportieren Sie erneut.
Was hat das Token getan?
Listen Sie jedes Ereignis mit diesem Hash auf (im Analyzer über Entitäten → Tokens → Ereignisse zeigen) und ordnen Sie die Aktionen drei Gruppen zu:
| Gruppe | Aktionen | Bedeutung |
|---|---|---|
| Lesen / Exfiltration | git.clone, git.fetch, repo.download_zip | Der Code (und jedes Secret in seiner Historie) ist draußen |
| Schreiben / Manipulation | git.push, workflows.created_workflow_run auf einem neuen Branch, protected_branch.destroy | Code oder Pipelines wurden verändert. Siehe GitHub-Actions-Secrets geleakt |
| Persistenz | public_key.create, hook.create, integration_installation.create, org.register_self_hosted_runner, personal_access_token.request_created | Zugriff, der den Widerruf überdauert |
Die Scopes des Tokens setzen die Grenzen. Ein klassisches Token mit repo und workflow kann Workflow-Dateien pushen. Mit admin:org kann es Einstellungen der Organisation ändern. Ein Fine-grained Token erreicht nur die Repositories und Berechtigungen, die ihm gewährt wurden; in Organisationen, die eine Genehmigung verlangen, zeigen die Ereignisse personal_access_token.request_created und .access_granted, wann es diesen Zugriff erhalten hat.
Entfernen, was das Token hinterlassen hat
Der Widerruf macht nicht rückgängig, was der Angreifer angelegt hat. Bevor Sie den Vorfall schließen:
- Löschen Sie unbekannte Deploy-Keys und SSH-Schlüssel (
public_key.create). Ein Deploy-Key mit Schreibrecht behält den Push-Zugriff nach jedem Zurücksetzen von Passwörtern und Tokens. - Entfernen Sie Webhooks, GitHub Apps, genehmigte OAuth-Apps und selbst gehostete Runner, die im fraglichen Zeitraum hinzugekommen sind.
- Löschen Sie die Branches des Angreifers und prüfen Sie
.github/workflowsauf jedem Branch, nicht nur auf dem Standard-Branch. - Rotieren Sie die Actions-Secrets, die jeder Workflow lesen kann, den das Token pushen konnte, und dann die Cloud-Schlüssel darunter (siehe den Weg in die Cloud).
- Suchen Sie nach weiteren Tokens desselben Inhabers, die von der IP-Adresse des Angreifers aus benutzt wurden. Pivotieren Sie nach der IP-Adresse, nicht nur nach dem Hash.
Dem nächsten Mal vorbeugen
- Legen Sie für die Organisation eine Richtlinie für Personal Access Tokens fest: klassische Tokens einschränken, eine maximale Lebensdauer erzwingen, eine Genehmigung für Fine-grained Tokens verlangen. Der Analyzer markiert, wenn diese Richtlinie geschwächt wird (
pat-policy-weakened). - Unter Enterprise Cloud gilt eine IP-Zulassungsliste auch für Personal Access Tokens und SSH-Schlüssel. Gestohlene Tokens funktionieren dann nur noch aus Ihren Netzen.
- Setzen Sie für Automatisierung lieber GitHub Apps mit kurzlebigen Installation-Tokens ein als langlebige PATs.
FAQ
Widerruft GitHub geleakte Tokens automatisch?
GitHub widerruft automatisch gültige OAuth-Tokens, GitHub-App-Tokens und Personal Access Tokens, die in ein öffentliches Repository oder einen öffentlichen Gist gepusht wurden. Tokens, die anderswo geleakt sind (in einem privaten Repository, einem CI-Protokoll, einem Chat, einem Infostealer-Dump), werden nicht für Sie widerrufen.
Wie finde ich die Ereignisse eines Tokens im Audit-Log?
Berechnen Sie seinen Hash mit echo -n TOKEN | openssl dgst -sha256 -binary | base64 und suchen Sie dann im Audit-Log nach hashed_token:"WERT". Beachten Sie, dass Suchen über UI und API keine Git-Events umfassen. Exportieren Sie diese, um Klonvorgänge zu prüfen.
Reicht es, das Token zu widerrufen?
Nein. Der Widerruf verhindert die künftige Nutzung, aber nicht, was der Angreifer bereits getan oder hinterlassen hat: SSH- und Deploy-Keys, OAuth-Apps, Workflows auf neuen Branches, Runner und Webhooks überdauern ihn. Bestimmen Sie den Umfang der Token-Aktivität, entfernen Sie Persistenz und rotieren Sie die Secrets, die seine Workflows lesen konnten.