GitHub-Aktionen nach echten Angriffen sperren
Eine kompromittierte Aktion ließ Geheimnisse aus Tausenden von Repos durchsickern. Was ich in meinem verändert habe.
Eine kompromittierte Aktion ließ Geheimnisse aus Tausenden von Repos durchsickern. Was ich in meinem verändert habe.

Lange Zeit habe ich GitHub Actions Workflows wie Sanitärtechnik behandelt. Kopieren Sie einen Workflow aus einem README, fügen Sie hinzu uses: some-org/some-action@v3Und weitermachen. Die meisten von uns haben es getan.
Im März 2025 wird die tj-actions/changed-files Action wurde gehackt. Die Angreifer haben die Versionen verändert, um auf einen bösartigen Code zu zeigen, der CI-Geheimnisse in die Build-Logs durchsickerte. Tausende von Repos haben es benutzt. Viele hatten öffentliche Protokolle. Es war ein Weckruf: Unsere Pipelines laufen mit Drittanbieter-Code mit Zugriff auf unsere vertraulichsten Anmeldeinformationen, und wir denken selten darüber nach.
Hier ist, was ich geändert habe, und was ich jedem empfehlen würde, der Aktionen verwendet.
Wenn du schreibst uses: tj-actions/changed-files@v45, v45 ist ein Git-Tag. Die Marken können verschoben werden. Wenn ein Angreifer Schreibzugriff auf das Repository der Aktion erhält, kann er vorhandene Tags auf einen bösartigen Commit richten. Jeder Workflow, der dieses Tag verwendet, führt den neuen Code beim nächsten Lauf aus, ohne dass sich etwas in Ihrem Repository ändert.
Die Untersuchung zeigte später, dass der Hacker selbst mit einer anderen kompromittierten Aktion verbunden war. Die Lieferkette greift die Lieferketten an.
Ihre Pipeline ist nur so vertrauenswürdig wie die am wenigsten vertrauenswerte Aktion, die sie durchführt.
Anstelle eines Tags, verweisen Sie auf den genauen Commit:
# Before
- uses: actions/checkout@v4
# After
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
Ein SHA-Kommando kann nicht verschoben werden. Die Version als Kommentar behalten, so dass Menschen es lesen können, und lassen Dependabot oder Erneuern Sie können die SHA (und den Kommentar) durch eine normale Pull-Anfrage aktualisieren, wenn eine neue Version veröffentlicht wird.
GitHub ermöglicht es Organisationen auch, SHA-Pinning in ihrer erlaubten Aktionsrichtlinie durchzusetzen, so dass nicht-gepinte Aktionen fehlschlagen.
Jeder Workflow erhält eine automatische GITHUB_TOKEN- Ich weiß . Die Standardberechtigungen hängen von Ihren Einstellungen ab, und in älteren Repositories sind sie oft viel zu breit.
Die Organisation oder das Repository als Standard-System auf nur Lesbar festlegen und nur das zugebe, was jeder Workflow benötigt:
permissions:
contents: read
jobs:
release:
permissions:
contents: write # only this job can push tags
Ein durchgesickertes Lesetoken ist ein viel kleines Problem als ein durchgesickeres Schreibtoken.
Die Geheimnisse, die bei diesen Angriffen durchgesickert sind, waren oft Cloud-Zugangsschlüssel, die gültig sind, bis jemand sie wechselt. Sie ersetzen OIDC: der Workflow fordert ein kurzlebiges Token von GitHub an, und Ihr Cloud-Provider tauscht es gegen temporäre Anmeldeinformationen aus, aber nur für das spezifische Repository und den Branch, den Sie zulassen.
permissions:
id-token: write
contents: read
steps:
- uses: aws-actions/configure-aws-credentials@<sha> # v4
with:
role-to-assume: arn:aws:iam::123456789012:role/deploy-shop
aws-region: eu-central-1
AWS, Azure, Google Cloud, HashiCorp Vault und viele andere unterstützen das. Kein Geheimnis zu stehlen, und das Token läuft in Minuten ab.
pull_request_target und workflow_run Sie haben Zugang zu Geheimnissen, sogar für Anfragen von Gabeln. Kombiniert mit der Überprüfung des nicht vertrauenswürdigen Codes aus der Pull-Anfrage, sind sie eine klassische Möglichkeit für Angreifer, Geheimnisse zu stehlen. Vermeide sie, es sei denn, du verstehst wirklich das Risiko.
Achten Sie auch auf Schriftinjektion: mit nicht vertrauenswürdigen Eingaben wie einem Pull-Request-Titel direkt in einem run: Schritt.
# Dangerous: the title can contain shell commands
- run: echo "${{ github.event.pull_request.title }}"
# Safer: pass it through an environment variable
- env:
TITLE: ${{ github.event.pull_request.title }}
run: echo "$TITLE"
In Organisations-Einstellungen dürfen nur:
Weniger Aktionen durch Dritte bedeuten weniger Dinge, die kompromittiert werden können. Für einfache Aufgaben sind ein paar Linien der Schale oft sicherer als eine Aktion.
Fügen Sie Zizmor zu Ihrem Informanten hinzu und reparieren Sie, was er findet. Es ist ein Augenöffner.
Wenn Sie nur drei Dinge in dieser Woche tun: Setzen Sie das Standard-Token auf nur-lesen, schließen Sie Ihre Drittanbieteraktionen an SHAs mit dem Update von Renovate an und ersetzen Sie einen langlebigen Cloud-Schlüssel durch OIDC. Dann laufen Sie mit Zizmor durch und arbeiten Sie die Liste durch.
Meine Meinung: CI-Pipelines halten den Schlüssel zu allem. Behandeln Sie alle uses: Die Linie ist wie eine Abhängigkeit, denn genau das ist sie.
Desly