Skip to content

Dieses Werkzeug ist weder mit GitHub, Inc. oder der Microsoft Corporation verbunden noch von ihnen unterstützt oder gesponsert. GitHub und GitHub Actions sind Marken von GitHub, Inc. Andere Namen sind Marken ihrer jeweiligen Inhaber.

Branch Protection deaktiviert? GitHub-Rulesets prüfen

Manipulierte Branch Protection oder Rulesets in GitHub untersuchen: protected_branch.destroy, Ruleset-Änderungen, Admin-Overrides, Umgebungen und neue Commits.

Veröffentlicht am 5 Min. Lesezeit

Kurz gesagt. Branch Protection und Rulesets verhindern, dass eine einzige gestohlene Zugangsberechtigung main umschreiben kann. Angreifer entfernen sie (protected_branch.destroy, repository_ruleset.destroy), schwächen sie ab (protected_branch.update_*, repository_ruleset.update) oder umgehen sie (protected_branch.policy_override). Mit Deployment-Umgebungen verfahren sie genauso (environment.remove_protection_rule). Das Audit-Log zeigt Ihnen, wer welche Regel wann geändert hat. Die Git-Historie und die Git-Events zeigen Ihnen, was in der Zwischenzeit eingespielt wurde. Stellen Sie die Regel wieder her und prüfen Sie dann jeden Push, jeden Force-Push und jedes Deployment in diesem Zeitfenster.

Code-Review, verpflichtende Statuschecks und signierte Commits sind Kontrollen für die Supply Chain. Sie wirken nur, solange sie durchgesetzt werden. Ein Angreifer mit Admin-Rechten oder dem Token eines Owners kann sie für die paar Minuten abschalten, die er braucht. Manche schalten sie danach wieder ein, um die Lücke zu verschleiern. Das Audit-Log behält beide Ereignisse.

Was manipuliert werden kann

KontrolleEntfernt / gelöschtAbgeschwächtUmgangen
Klassische Branch Protectionprotected_branch.destroyprotected_branch.update_* (Anzahl der Reviews, Statuschecks, Force-Pushes, Löschungen, Durchsetzung für Admins …)protected_branch.policy_override
Repository-Rulesetsrepository_ruleset.destroyrepository_ruleset.updateim Ruleset konfigurierte Bypass-Akteure
Deployment-Umgebungenenvironment.deleteenvironment.remove_protection_rule, environment.update_protection_rule—

GitHubs Dokumentation zu geschützten Branches und zu Rulesets beschreibt jede Einstellung. Der Glossareintrag zu Repository-Rulesets erklärt, wie Rulesets und klassischer Branch-Schutz zusammenwirken.

Wie der Analyzer das erkennt

RegelAktionenSchweregrad
branch-protection-removedprotected_branch.destroy, repository_ruleset.destroyhoch
branch-protection-overrideprotected_branch.policy_overridemittel
environment-protection-removedenvironment.remove_protection_rule, environment.deletehoch

Befunde werden nach Repository gruppiert. Die abschwächenden Aktionen (protected_branch.update_*, repository_ruleset.update) sind keine Regeln, weil sie zur normalen Verwaltung eines Repositories gehören. Sie erscheinen in der Zeitleiste, weil dort jede Aktion mit protected_branch. und repository_ruleset. erhalten bleibt. Schlägt ein Befund an, öffnen Sie die Zeitleiste für dieses Repository und lesen Sie die Änderungen rund um den Befund.

Eine Entfernung lesen

Ein Ereignis protected_branch.destroy enthält das Repository, das Branch-Muster (name) und die Einstellungen der Regel zum Zeitpunkt der Löschung, etwa required_approving_review_count und admin_enforced. Daran sehen Sie, was verloren ging. Beantworten Sie dann vier Fragen:

  1. Wer und womit? Akteur, IP-Adresse, User-Agent und hashed_token. Eine Browser-Sitzung aus dem Büro des Owners ist etwas anderes als curl/8.5.0 mit einem Token von einem VPS.
  2. Wurde die Regel wiederhergestellt, und von wem? Ein protected_branch.create für denselben Branch Stunden später, durch einen anderen Akteur, bedeutet meist, dass es jemandem aufgefallen ist. Legt derselbe Akteur die Regel Minuten später neu an, deutet das auf Verschleierung hin.
  3. Was wurde dazwischen gepusht? Filtern Sie die Git-Events nach git.push auf dieses Repository im Zeitfenster und vergleichen Sie mit der Commit-Historie des Branches. Git-Events enthalten keine Pushes über die Weboberfläche oder die API, prüfen Sie also zusätzlich die Aktivitätsansicht des Repositories.
  4. Wurde etwas deployt? Workflow-Läufe auf dem Standard-Branch im Zeitfenster (workflows.created_workflow_run mit head_branch: main) könnten die Änderung ausgeliefert haben.

Overrides sind etwas anderes

protected_branch.policy_override bedeutet, dass ein Repository-Administrator gepusht oder gemergt hat, während die Regel in Kraft blieb, indem er sein Bypass-Recht genutzt hat. Das ist oft legitim: Hotfixes oder Release-Manager mit dokumentierter Ausnahme. Deshalb ist es mit mittel bewertet. Interessant wird es, wenn das Admin-Konto zugleich Befunde zu Tokens oder Standorten aufweist oder wenn sich Overrides auf sensiblen Pfaden wie .github/workflows/ häufen.

Umgebungen: die Secrets hinter der Schranke

Schutzregeln für Umgebungen (erforderliche Reviewer, Wartezeiten, Richtlinien für Deployment-Branches) sind oft das Einzige, was zwischen einem Workflow auf einem beliebigen Branch und den Produktions-Zugangsdaten für die Cloud steht, die als Umgebungs-Secrets gespeichert sind. Wird eine Regel entfernt oder die Umgebung gelöscht und neu angelegt, sind diese Secrets für jeden Workflow-Lauf erreichbar, der auf die Umgebung verweist. Nach einem Befund environment-protection-removed listen Sie die Läufe auf, die diese Umgebung im Zeitfenster verwendet haben, und behandeln ihre Secrets als offengelegt. Der Artikel zu Actions-Secrets beschreibt, wie Sie den Umfang bestimmen.

Force-Pushes und umgeschriebene Historie

Regeln blockieren oft Force-Pushes. Ist der Schutz aus, kann ein Angreifer die Historie umschreiben, um einen bösartigen Commit einzuschleusen oder die Spuren eines solchen zu beseitigen. Das Audit-Log zeichnet keine Commit-Inhalte auf, aber Sie können trotzdem mit Folgendem arbeiten:

  • git.push-Ereignisse (sofern Git-Events vorliegen) für den Zeitpunkt und die verwendete Zugangsberechtigung.
  • protected_branch.update_allow_force_pushes_enforcement_level, falls der Angreifer nur diese Einstellung gelockert hat.
  • Die Aktivitätsansicht des Repositories sowie Ihre Mirrors oder CI-Caches. Sie enthalten womöglich noch die Commits vor dem Umschreiben.

Die Lücke von Hand vermessen

Wenn Sie die Auswertung des Analyzers überprüfen wollen oder nur den Rohexport haben, ist die Abfrage kurz. Extrahieren Sie jedes Schutz- und Ruleset-Ereignis des Repositories in zeitlicher Reihenfolge, mit Akteur und IP-Adresse:

jq -r '.[] | select(.repo=="ORG/REPO")
  | select(.action|test("^(protected_branch|repository_ruleset|environment)\\."))
  | [(.["@timestamp"]/1000|todate), .action, .actor, (.actor_ip // "-"), (.name // "-")]
  | @tsv' audit-log.json | sort

Lesen Sie die Ausgabe paarweise. Auf jedes destroy oder update, das eine Regel schwächt, sollte ein create oder update folgen, das sie wiederherstellt. Die Zeit dazwischen ist Ihr Expositionsfenster. Notieren Sie es in UTC, denn alles Weitere bei der Bestimmung des Umfangs (Pushes, Workflow-Läufe, Deployments) wird nach diesem Fenster gefiltert. Fehlt die passende Wiederherstellung, ist das Fenster noch offen. Beheben Sie das, bevor Sie weiter ermitteln. Prüfen Sie außerdem, ob Abschwächung und Wiederherstellung vom selben Konto kamen. Wenn eine Person den Schutz rund um einen einzigen Push ab- und wieder einschaltet, müssen Sie mit dieser Person sprechen, ganz gleich, welcher Grund sich am Ende herausstellt.

Checkliste zur Bereinigung

  • Legen Sie Branch Protection und Rulesets aus einer bekannt guten Definition neu an (Rulesets als Code pflegen oder exportieren).
  • Stellen Sie die Schutzregeln der Umgebungen wieder her und rotieren Sie die Secrets der Umgebung.
  • Prüfen Sie jeden Commit, Merge, Force-Push und jedes Deployment aus der Zeit der Lücke, und setzen Sie zurück oder deployen Sie neu von einem vertrauenswürdigen Commit.
  • Entfernen Sie unerwartete Bypass-Akteure aus Rulesets und unerwartete Repository-Admins.
  • Bevorzugen Sie für die wichtigsten Kontrollen Rulesets auf Organisationsebene. Sie werden auf Ebene der Organisation verwaltet, nicht von den Admins des jeweiligen Repositories.

Verwandte Artikel

Verwandte Artikel

Anzeichen für die Übernahme einer GitHub-Organisation im Audit-Log: neue Owner, 2FA-Pflicht aus, SAML-SSO geändert, IP-Zulassungsliste aus, Streaming entfernt.
GitHub-Organisation kompromittiert? Audit-Log sichern, Tokens und Workflows eindämmen, Umfang mit Git-Events bestimmen und dann in die Cloud weiterermitteln.
Was das GitHub-Audit-Log nicht erfasst: 180 bzw. 7 Tage Aufbewahrung, Plangrenzen für API und Git-Events, verborgene IPs, keine Dateiinhalte, kein Secret-Lesen.

Dieses Werkzeug ist weder mit GitHub, Inc. oder der Microsoft Corporation verbunden noch von ihnen unterstützt oder gesponsert. GitHub und GitHub Actions sind Marken von GitHub, Inc. Andere Namen sind Marken ihrer jeweiligen Inhaber.