Blog
GitHub Actions - Lehren aus dem jüngsten nx-Hack

Sie haben vielleicht die jüngsten Berichte über die Kompromittierung des nx-Projekts gesehen. Eine bösartige Version ihres Pakets wurde auf npmjs veröffentlicht, die anschließend GitHub-Token, Krypto-Wallets und andere sensible Daten von Tausenden von Benutzern veröffentlichte.
Die Betreuer des Projekts haben genau dargelegt, wie das Projekt kompromittiert wurde. Es wird jedoch nicht genau gesagt, was sie getan haben, um zu verhindern, dass das gleiche Problem in Zukunft auftritt. Oder wie Sie sich vor diesen Angriffsvektoren schützen können.
Ich gehe die Angriffskette durch und erkläre, welche Möglichkeiten Ihnen zur Verfügung stehen, um diese Dinge zu verhindern.
Den gefährdeten Arbeitsablauf verstehen
Schauen wir uns die Hauptursache für diesen Hack an. Die Einführung eines neuen GitHub Actions Workflows, bei dem der Auslöser pull_request_target
aktiviert war. Dieser Auslöser ist gefährlich, da er GitHub signalisiert, dass der Workflow sicher ist und Zugriff auf Geheimnisse hat. Standardmäßig nur auf Geheimnisse, auf die im Workflow selbst verwiesen wird, aber dazu gehört immer auch das integrierte GitHub Actions Token.
on:
pull_request_target:
types: [opened, edited, synchronize, reopened]
Die zweite Stufe des Hacks wurde durch eine Skriptinjektion im selben Workflow möglich. Dadurch konnte über den Titel der Pull-Anfrage beliebiger Code in die Pipeline eingeschleust werden:
- name: Create PR message file
run: |
mkdir -p /tmp
cat > /tmp/pr-message.txt << 'EOF'
${{ github.event.pull_request.title }}
${{ github.event.pull_request.body }}
EOF
Der Titel und der Text der Pull-Anfrage werden vor der Ausführung in das Skript geschrieben, so dass das Einfügen von EOF
als beliebiger Bash-Befehl interpretiert werden würde. Und das Hinzufügen von$(...)
würde ebenfalls zur Ausführung von Code führen, bevor der Inhalt in pr-message.txt
geschrieben wird.
Da der Workflow nun beliebigen Code ausführen kann und der GitHub Hosted Runner standardmäßig mit sudo läuft, wäre es auch möglich, einen Speicherauszug des Runner-Prozesses zu schreiben, um Zugriff auf das GitHub-Token des Runners zu erhalten.
Die Nutzdaten waren wahrscheinlich im Text des Pull Request versteckt und könnten etwa so lauten:
# Break the multi-line content redirection by supplying the defined EOF token.
EOF
# Dump the listener process so we can get access to its secrets
sudo apt-get install -y gdb && \
sudo gcore -o k.dump "$(ps ax | grep 'Runner.Listener' | head -n 1 | awk '{ print $1 }')"
# Then, we grep the memory dump for the format of secret values—per the job data we decrypted in the network analysis:
grep -Eao '"[^"]+":\{"value":"[^"]*","issecret":true\}' k.dump*
# Optionally use CURL to send these secrets to a url you control.
# Possibly a GitHub webhook url on another project traffic doesn't stand out.
Dies ist eine bekannte Methode, um Geheimnisse aus dem GitHub Hosted Runner zu exfiltrieren, und ich vermute, dass sie benutzt wurde, um an das Geheimnis GITHUB_TOKEN zu gelangen.
Da dieses Token über alle Schreibrechte verfügt, ist es möglich, entweder in einen ungeschützten Zweig des Repos zu schreiben oder andere Workflows auszuführen. Der Workflow publish.yml
konnte manuell in der Verzweigung master
ausgelöst werden. Das bedeutet, dass er für jede beliebige Verzweigung im Projekt-Repository ausgelöst werden kann und den Inhalt des Workflows in dieser speziellen Verzweigung verwendet. Da das npm-Token als Repository-Geheimnis gespeichert ist, steht es allen Workflows im Repository zur Verfügung, unabhängig davon, in welchem Zweig es definiert ist.
In diesem Fall hätte ich den GitHub Token dazu verwenden können:
- Erstellen Sie einen neuen Zweig im Projekt-Repository
- Überschreiben Sie die publish.yml im neuen Zweig, um das npm-Token an einen von mir kontrollierten Webserver zu senden
- Den Veröffentlichungsworkflow für meinen Zweig auslösen
- Löschen Sie die Verzweigung
- Löschen Sie optional den Workflow-Lauf
Ohne die publish.yaml zu überschreiben, hätten Änderungen in den Build-Skripten, die im Veröffentlichungsauftrag ausgeführt werden, Zugriff auf das Token gehabt, da es als Umgebungsvariable auf Auftragsebene hinzugefügt wurde.
publish:
if: ${{ github.repository_owner == 'nrwl' }}
env:
GH_TOKEN: ${{ github.token }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
In der Offenlegung erwähnt das Projekt, dass es Zweigregeln zum Schutz des Master-Zweigs eingerichtet hat. Ohne Zweigschutz wäre dies noch einfacher gewesen.
Den verletzlichen (menschlichen) Prozess verstehen
Dieser Angriff hätte nicht stattfinden können, wenn der obige Workflow nicht hinzugefügt worden wäre oder wenn stattdessen der Standardauslöser pull_request
verwendet worden wäre. Wenn Sie die Dokumentation zu pull_request_target
lesen, werden Sie auf die Gefahr hingewiesen.
Es sieht so aus, als ob dieser Workflow von KI generiert wurde:
🤖 Generated with Claude Code
Und dass keiner der Menschen in diesem Kreislauf sich der Gefahren bewusst war. Es gab auch keine Werkzeuge, um die Arbeitsabläufe zu überprüfen und sie auf mögliche Probleme aufmerksam zu machen.
Sobald der Angreifer die Angriffskette herausgefunden hat, wäre es möglich gewesen, den Angriff innerhalb von Sekunden auszuführen, mit nur minimalen beobachtbaren Spuren. Und da alle Aktionen von dem Benutzer github-actions[bot]
durchgeführt würden, würde keine der Änderungen auffallen und alle Commits würden sogar als verifiziert gelten, wenn sie korrekt durchgeführt werden.
Es ist trivial einfach, ein Repo einzurichten, in dem Sie diesen Angriff testen können, ohne mit dem nx Repo interagieren zu müssen.
Da das NPM-Token als Repository-Geheimnis gespeichert wurde, wäre für den Zugriff darauf keine ausdrückliche Genehmigung erforderlich.
Das hat zwar nichts mit diesem Angriff zu tun, ist aber dennoch beunruhigend: Die Aktionen, auf die das nx-Projekt verweist, sind an ihr Hauptversions-Tag gepinnt. Dies verstößt gegen die Best Practices für GitHub-Aktionen in öffentlichen Repos. Zum Beispiel:
- uses: actions/checkout@v4
Bewährte Praktiken verlangen, dass jede Aktion an ihr Commit Sha angeheftet wird. In diesem Fall hat, soweit ich das beurteilen kann, keine der referenzierten Aktionen eine bekannte Schwachstelle, aber das macht das Projekt offen für Angriffe, die dem tj-actions/changed-files-Hack von vor ein paar Monaten ähneln:
Abhilfe
Schauen wir uns an, welche Abhilfemaßnahmen ergriffen werden können (und welche für neue Unternehmen Standard sind):
- Ändern Sie die Standardberechtigungen für GitHub-Aktionen auf schreibgeschützt.
- Workflow-Berechtigungen auf Auftragsebene festlegen
- Aktivieren Sie Zweigregelsätze, um Pull Requests für alle wichtigen Zweige zu verlangen.
- Für die Ausführung von Fork-Pull-Request-Workflows benötigen Sie die Genehmigung von Mitwirkenden
- Verlassen Sie sich nicht auf
pull_request_target
. - Verwenden Sie keine
workflow_dispatch
oderrepository _dispatch
Auslöser in Arbeitsabläufen, die Zugriff auf kritische Geheimnisse haben. - Vermischen Sie keine Pull-Request-Validierung und kontinuierliche Integrationsabläufe
- Speichern Sie kritische Geheimnisse in Umgebungsgeheimnissen anstelle von Repository-Geheimnissen.
- Geben Sie Geheimnisse nur an die Schritte weiter, die sie benötigen
- Übergeben Sie Daten an Skriptschritte unter Verwendung der Umgebung
- Binden Sie alle Aktionen an ihr Sha.
- Aktivieren Sie GitHub Advanced Security Code Scanning für GitHub-Aktionen und fügen Sie Branch Ruleset hinzu.
- Aktivieren Sie Dependabot für GitHub-Aktionen, um Aktionsreferenzen automatisch auf die neueste Version zu aktualisieren.
- Ziehen Sie Sicherheitshärtungstools von Drittanbietern wie Harden Runner von StepSecurity in Betracht.
Jede dieser Abhilfemaßnahmen wird im Folgenden ausführlicher erläutert.
Ändern Sie die Standardberechtigungen für GitHub-Aktionen auf schreibgeschützt
Als GitHub Actions zum ersten Mal veröffentlicht wurde, waren die Standardberechtigungen auf "Alles schreiben" eingestellt. Als GitHub später die Standardberechtigung auf "Alles lesen" änderte, wurde die Berechtigung für bestehende Konten und Organisationen nicht rückwirkend zurückgesetzt.
Besitzer von GitHub Enterprise und GitHub Organization können über die Einstellungen die Standardberechtigung "Alles lesen" erzwingen:

Dadurch werden alle Arbeitsabläufe unterbrochen, die nicht explizit ihre erforderlichen Berechtigungen angeben, falls sie mehr als nur die Leseberechtigung benötigen.
Wenn Sie schon dabei sind, sollten Sie auch die Option GitHub-Aktionen zum Erstellen und Genehmigen von Pull Requests zulassen deaktivieren. Wenn Sie diese Einstellung zulassen, können Angreifer unter bestimmten Bedingungen die Regeln für Verzweigungen aushebeln.
Workflow-Berechtigungen auf Auftragsebene festlegen
Ein Workflow kann seine erforderlichen Berechtigungen auf Workflow- oder auf Auftragsebene festlegen. Für optimale Sicherheit empfiehlt es sich, alle Berechtigungen auf Workflow-Ebene zu verweigern und die Berechtigungen explizit für jeden einzelnen Auftrag zu deklarieren:
# Opt out of any default permissions
permissions: {}
jobs:
build:
# explicitly request permissions
permissions:
contents: read
deploy:
permissions:
contents: read
packages: write
Dadurch werden auch die Schreibberechtigungen entfernt, falls die Standardberechtigungen auf Lesen und Schreiben eingestellt sind.
Aktivieren Sie Zweigregelsätze, um Pull Requests für alle wichtigen Zweige zu verlangen.
Das nx-Projekt berichtet, dass es Branch Rulesets aktiviert hat, um eine Pull-Anfrage für alle Änderungen zu verlangen, die in den Master-Zweig und andere wichtige Zweige des Repositorys gelangen sollen.
Dies hinderte Angreifer daran, einfach einen neuen Workflow direkt in den Hauptzweig zu pushen, um das npm-Token und andere Geheimnisse zu exfiltrieren.
Der Schutz von Zweigen in Ihrem Repository ist eine einfache Konfigurationsänderung.

Dies ist auch eine Voraussetzung für andere Schutzmaßnahmen, wie z.B. die Forderung nach Code-Scan-Ergebnissen vor dem Zusammenführen.
Es gibt eine ganze Reihe von Richtlinieneinstellungen, die Sie über Branch Rulesets aktivieren können. Im Folgenden wird erläutert, warum jede dieser Einstellungen wichtig ist und wie ein Angreifer ein Ruleset mit einer etwas weniger strengen Konfiguration missbrauchen könnte:
Erfordern Sie die Zustimmung von Mitwirkenden für die Ausführung von Fork-Pull-Anfrage-Workflows
Dies ist ein umstrittenes Thema. Denn es bedeutet einen erheblichen Mehraufwand für Projektteams, die viele Beiträge von Drittanbietern erhalten. Aber es könnte ausreichen, dass ein Betreuer den Skriptinjektionsangriff entdeckt, mit dem das GitHub Actions-Token exfiltriert wurde.
GitHub Enterprise Owner, Organization Owner und Repository Admins können eine Richtlinie festlegen, die eine Genehmigung vor der Ausführung eines GitHub Actions Workflows erfordert.

Es mag zwar verlockend sein, diese Richtlinie auf eine der leichteren Einstellungen zu setzen, aber es gibt bereits bekannte Fälle, in denen eine Person hilfreich erscheint, indem sie ein paar Tippfehler korrigiert. Danach wird sie als vertrauenswürdig eingestuft.
Wenn Sie diese Richtlinie festlegen, muss ein Betreuer den Pull Request überprüfen und die Arbeitsabläufe jedes Mal auslösen, wenn ein externer Mitarbeiter neue Commits einreicht.
Verlassen Sie sich nicht auf pull_request_target
Die pull_request_target
ist von Natur aus gefährlich. Es eröffnet Ihnen alle möglichen zusätzlichen Angriffsmöglichkeiten, und nur sehr wenige Menschen sind sich der Tragweite bewusst. Wenn Sie diesen Auslöser für einen Workflow aktivieren, können Sie sehr leicht einen Fehler machen und Ihr Repository für Angriffe öffnen.
Ich empfehle Ihnen, sich nicht auf den pull_request_target
Auslöser zu verlassen. Für die meisten Szenarien ist der pull_request
Auslöser ausreichend.
In den Unternehmen, die ich kontrolliere, haben wir ein benutzerdefiniertes Muster für Secret Scanning hinzugefügt , um alle Commits zu blockieren, die pull_request_target
enthalten:

Und wir haben dieses Muster für den Push-Schutz aktiviert:

Es gibt zwar Fälle, in denen pull_request_target
nützlich sein kann, aber im Allgemeinen ist es die Sicherheitsrisiken nicht wert.
⚠️ Warnung
Für Arbeitsabläufe, die durch den pull_request_target
Ereignis, das GITHUB_TOKEN
erhält Lese-/Schreibrechte für das Repository, es sei denn, der permissions
Schlüssel angegeben ist und der Workflow auf Geheimnisse zugreifen kann, auch wenn er von einem Fork ausgelöst wird. Obwohl der Workflow im Kontext der Basis des Pull Requests ausgeführt wird, sollten Sie sicherstellen, dass Sie mit diesem Ereignis keinen nicht vertrauenswürdigen Code aus dem Pull Request auschecken, bauen oder ausführen. Außerdem haben alle Caches den gleichen Geltungsbereich wie der Basiszweig. Um Cache Poisoning zu verhindern, sollten Sie den Cache nicht speichern, wenn die Möglichkeit besteht, dass der Inhalt des Caches verändert wurde. Für weitere Informationen siehe Wie Sie Ihre GitHub-Aktionen und Arbeitsabläufe sicher halten: Verhindern von pwn-Anfragen auf der Website des GitHub Security Lab.
Verwenden Sie keine workflow_dispatch
oder repository_dispatch
Auslöser in Arbeitsabläufen, die Zugang zu kritischen Geheimnissen haben.
Da workflow_dispatch
und repository_dispatch
es einem Angreifer ermöglichen, den Zweig zu kontrollieren, gegen den der Arbeitsablauf läuft, kann er dazu verwendet werden, Geheimnisse des Repositorys auszuspionieren, wenn der Angreifer Schreibzugriff auf einen anderen Zweig des Repositorys hat.
Die einzige Möglichkeit, Geheimnisse vor diesem Angriffsweg zu schützen, besteht darin, sie als Umgebungsgeheimnis zu speichern.
Vermischen Sie keine Pull-Request-Validierung und kontinuierliche Integrationsabläufe
Viele Entwickler versuchen, Doppelarbeit zu vermeiden, indem sie mehrere Workflows zu einem einzigen zusammenfassen und mehrere Auslöser oder Bedingungen definieren. Diese Bedingungen steuern dann, welcher Code abhängig von dem Ereignis, das den Workflow ausgelöst hat, ausgeführt wird.
Ein sehr gängiges Beispiel ist ein einziger Arbeitsablauf zur Validierung von Pull-Anfragen, der gleichzeitig die ersten Schritte des vollständigen CI-Builds darstellt.
Die publish.yml
im nx
Projekt hat 3 solcher Zwecke:
- Geben Sie die Pakete für das nx-Projekt frei, wenn ein neues Tag erstellt wird
- Freigabe eines Kanarienvogels auf der Grundlage eines Zeitplans
- Erstellung eines Test-Builds für Pull Requests
name: publish
on:
# Automated schedule - canary releases from master
schedule:
- cron: "0 3 * * 2-6" # Tuesdays - Saturdays, at 3am UTC
# Manual trigger - PR releases or dry-runs (based on workflow inputs)
workflow_dispatch:
inputs:
pr:
description: "PR Number - If set, a real release will be created for the branch associated with the given PR number. If blank, a dry-run of the currently selected branch will be performed."
required: false
type: number
release:
types: [ published ]
Das Projekt nx
erreicht dies, indem es die Build- und Veröffentlichungsaufträge so einschränkt, dass sie nur ausgeführt werden, wenn das auslösende Repository nrwl
gehört.
build:
if: ${{ github.repository_owner == 'nrwl' }}
publish:
if: ${{ github.repository_owner == 'nrwl' }}
Dies würde verhindern, dass der Veröffentlichungsauftrag gegen Pull-Anfragen aus einem geforketen Repository läuft.
Da das durchgesickerte Token jedoch über eine Schreibberechtigung verfügte, wäre es ein Leichtes gewesen, einen neuen Zweig zu veröffentlichen, der die Bedingung repository_owner
erfüllt und somit die Veröffentlichungsaufträge auslöst.
Es hätten noch weitere Einschränkungen hinzugefügt werden können, z.B. die Überprüfung, ob der Akteur ein Maintainer ist, oder die Verhinderung von Workflows, die durch GitHub-Aktionen ausgelöst werden, oder die Beschränkung von Jobs auf bestimmte Zweige. Aber wenn der Angreifer Schreibrechte für das Repository hat, wird Sie wahrscheinlich keine dieser Maßnahmen retten.
Ein besserer Ansatz wäre es, den Arbeitsablauf in 2 separate Arbeitsabläufe aufzuteilen:
publish.yaml
- die die Produktionspakete veröffentlichtpr-validation.yaml
- das ein PR-Validierungspaket erstellt
Diese beiden Workflows können einen 3. aufrufbaren Workflow oder eine oder mehrere zusammengesetzte Aktionen verwenden, um Code-Duplizierung zu reduzieren und gleichzeitig die Wahrscheinlichkeit zu verringern, dass ein Angreifer einen Workflow aufruft, den er nicht aufrufen soll.
Ein weiterer Vorteil von aufrufbaren Workflows und zusammengesetzten Aktionen besteht darin, dass sie in einem anderen Repository gespeichert werden können, was die Möglichkeiten eines Angreifers einschränkt, ein geleaktes Actions Token zu nutzen, um den Workflow-Code zu ändern.
Speichern Sie kritische Geheimnisse in Umgebungsgeheimnissen anstelle von Repository-Geheimnissen.
Auf der Repository-Ebene definierte Geheimnisse sind für alle Workflows zugänglich. Es gibt keine Möglichkeit, den Zugriff auf Geheimnisse auf Repository-Ebene zu beschränken.
Um ein wichtiges Geheimnis zu schützen, wie z.B. das NPM-Token, das zur Veröffentlichung Ihres Pakets verwendet wird, sollte es als Umgebungsgeheimnis definiert werden.
In der Umgebungsrichtlinie können Sie dann eine Zweigstellenrichtlinie festlegen, um einzuschränken, welche Zweigstellen Zugriff auf das Geheimnis haben.

Fügen Sie optional Erforderliche Prüfer hinzu, um den Zugriff auf die Geheimnisse ohne manuelle Genehmigung zu verhindern:

Aktualisieren Sie dann den Workflow, um bei der Definition des Auftrags auf die Umgebung zu verweisen:
jobs:
deploy:
environment: public
steps:
uses: actions/deploy@sha
with:
npm_token: ${{ secrets.NPM_TOKEN }}
Es sieht so aus, als ob das nx
Projekt dies bereits in einer kürzlich vorgenommenen Änderung umgesetzt hat:
Geben Sie Geheimnisse nur an die Schritte weiter, die sie benötigen
Im nx-Repository ist NPM_AUTH_TOKEN
auf der Ebene des Auftrags definiert:
publish:
env:
# DO NOT USE THIS!
GH_TOKEN: ${{ github.token }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
steps:
- ...
Dadurch sind die Geheimnisse für alle Schritte des Workflows verfügbar. Wenn der Angreifer die Kontrolle über einen der in diesen Schritten ausgeführten Codes übernehmen kann, wäre er in der Lage, das Geheimnis zu exfiltrieren.
In diesem Fall ruft der Auftrag auch pnpm build:wasm
auf, was eine Reihe zusätzlicher Verstecke für den Exfiltrationscode bietet.
Es ist besser, die Geheimnisse ausdrücklich nur an die Schritte weiterzugeben, die sie benötigen:
publish:
env:
# NO SECRETS SET HERE
steps:
- ...
- ...
- name: Publish
env:
VERSION: ${{ needs.resolve-required-data.outputs.version }}
DRY_RUN: ${{ needs.resolve-required-data.outputs.dry_run_flag }}
PUBLISH_BRANCH: ${{ needs.resolve-required-data.outputs.publish_branch }}
NX_VERBOSE_LOGGING: true
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
echo ""
# Create and check out the publish branch
git checkout -b $PUBLISH_BRANCH
echo ""
echo "Version set to: $VERSION"
echo "DRY_RUN set to: $DRY_RUN"
echo ""
pnpm nx-release --local=false $VERSION $DRY_RUN
Übergabe von Daten an Skriptschritte unter Verwendung der Umgebung
Der Skript-Injection-Angriff war möglich, weil Variablen im Textkörper eines Skriptschrittes eingefügt wurden:
- name: Create PR message file
run: |
mkdir -p /tmp
cat > /tmp/pr-message.txt << 'EOF'
${{ github.event.pull_request.title }} <- unsafe variable reference
${{ github.event.pull_request.body }} <- unsafe variable reference
EOF
Um Daten sicher an Skripte zu übergeben, sollten Sie sie stattdessen über die Umgebung übergeben:
- name: Create PR message file
run: |
mkdir -p /tmp
echo $PR_TITLE >> /tmp/pr-message.txt
echo "" >> /tmp/pr-message.txt
echo $PR_BODY >> /tmp/pr-message.txt
env:
PR_TITLE: ${{ github.event.pull_request.title }}
PR_BODY: ${{ github.event.pull_request.body }}
Script Injection kann sowohl von GitHub Advanced Security Code Scanning for Actions als auch von ActionLint erkannt werden.
Heften Sie alle Aktionen an ihr Sha.
Der Angriff auf nx scheint sich nicht auf diesen Angriffsvektor gestützt zu haben, aber der jüngste Angriff auf tj-actions/changed-files hat erneut gezeigt, dass es gefährlich ist, sich nur auf den Tag zu verlassen, um auf Aktionen von Drittanbietern zu verweisen.
GitHub empfiehlt, dass Sie Aktionen, die Sie nicht kontrollieren, immer mit ihrem expliziten Commit Sha referenzieren.
Zum Beispiel:
- uses: actions/checkout@v4
Hätten Sie verwenden sollen:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5

Da es sich um eine neue Richtlinie handelt, müssen sich GitHub-Administratoren ausdrücklich für diese Richtlinie entscheiden.
Es gibt verschiedene Tools, die das Anheften für Sie übernehmen:
Nach dem Anheften wird Dependabot, falls aktiviert, automatisch eine Pull-Anfrage mit dem korrekten neuen Commit-Sha einreichen. Leider ändert es den Tag v4
nicht automatisch in sein sha.
Aktivieren Sie GitHub Advanced Security Code Scanning für GitHub-Aktionen und fügen Sie Branch Ruleset hinzu.
Die Skriptinjektionsschwachstelle, die diesem Angriff zugrunde liegt, wäre von GitHub Advanced Security Code Scanning für GitHub Actions entdeckt worden.
GitHub Advanced Security ist für alle öffentlichen Repos kostenlos, so dass es eigentlich keinen guten Grund gibt, es nicht zu aktivieren.
Da die Unterstützung für GitHub-Aktionen erst kürzlich hinzugefügt wurde, müssen GitHub-Repository-Besitzer GitHub-Aktionen in der Code-Scanning-Konfiguration ausdrücklich aktivieren:

Oder fügen Sie actions
zur Liste der unterstützten Sprachen in ihrem Workflow hinzu:
jobs:
analyze:
name: Analyze (${{ matrix.language }})
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
permissions:
security-events: write
packages: read
actions: read
contents: read
strategy:
fail-fast: false
matrix:
include:
# Make sure Actions is added to the list of languages:
- language: actions
build-mode: none
Damit werden eine Reihe von Sicherheitslücken in GitHub Actions aufgespürt, darunter:
- Skript Injektion
- Unsicherer Checkout
Um zu verhindern, dass Workflows mit diesen Schwachstellen in das Repository gelangen, fügen Sie einen Verzweigungsregelsatz hinzu, der voraussetzt, dass der Code QL-Workflow erfolgreich ist:

Und verlangen Sie Code Scanning Ergebnisse:

Eine Alternative für GitHub Advanced Security Code Scanning for Actions, die auch die Script Injection-Schwachstelle entdeckt hätte, ist ActionLint. Actionlint kann auch als Workflow hinzugefügt werden.
Aktivieren Sie Dependabot für GitHub-Aktionen, um Aktionsreferenzen automatisch auf die neueste Version zu aktualisieren.
Um Ihre referenzierten GitHub-Aktionen automatisch auf dem neuesten Stand zu halten, insbesondere wenn Sie an die vollständige Commit-Sha anheften, können Sie Dependabot aktivieren, automatisch eine Pull-Anfrage zu erstellen, sobald eine Aktion aktualisiert wird.
Um Dependabot für GitHub Actions zu aktivieren, fügen Sie explizit github-actions
zu Ihrem .github/dependabot.yml
hinzu:
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
Um den Aufwand für die Betreuer zu verringern, können Sie mit GitHub Actions Aktualisierungen vollständig automatisieren.
Ziehen Sie Sicherheitshärtungstools von Drittanbietern wie Harden Runner von StepSecurity in Betracht.
Alle oben genannten Abhilfemaßnahmen sind integrierte Funktionen der GitHub-Plattform.
Es gibt Lösungen von Drittanbietern, mit denen Sie GitHub-Aktionen weiter absichern können. Von diesen ist der Harden Runner von StepSecurity wahrscheinlich die bekannteste Option. Sie können harden-runner zu jedem Workflow hinzufügen, indem Sie einen einzelnen Schritt zu Ihren Workflow-Jobs hinzufügen:
steps:
- name: Harden Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
Die Community-Version von Harden runner bietet die folgenden Schutzfunktionen für alle Arbeitsabläufe:
- CI/CD-gerechte Ereigniskorrelation: Jede ausgehende Netzwerkverbindung, jede Dateioperation und jede Prozessausführung wird genau dem Schritt, Job und Workflow zugeordnet, in dem sie auftritt.
- Automatisierte Erstellung der Baseline: Harden-Runner erstellt für jeden Auftrag eine Baseline auf der Grundlage der bisherigen ausgehenden Netzwerkverbindungen.
- Erkennung von Anomalien: Sobald die Baseline erstellt ist, werden alle zukünftigen ausgehenden Anrufe, die nicht in der Baseline enthalten sind, erkannt.
- Blockieren Sie ausgehenden Netzwerkverkehr mit der Domain Allowlist: Verwenden Sie optional die automatisch erstellte Baseline, um den ausgehenden Netzwerkverkehr durch die Angabe zulässiger Domänen zu kontrollieren und so eine nicht autorisierte Datenexfiltration zu verhindern.
- Erkennen Sie Änderungen am Quellcode: Überwachen Sie unautorisierte Änderungen an Ihrem Quellcode während der CI/CD-Pipeline und schlagen Sie Alarm.
Fazit
GitHub bietet viele Funktionen zum Schutz Ihres Projekts vor Angriffen, die versuchen, GitHub-Aktionen zu missbrauchen. Leider erfordern viele dieser Funktionen eine ausdrückliche Zustimmung oder Konfiguration.
Dies sollte keine Ausrede sein, um Ihre Open-Source-Projekte angreifbar zu machen.
Liebes GitHub,
Wir lieben die uneingeschränkt freie Umgebung und all die Tools, die Sie bereitstellen, um unsere Open-Source-Projekte frei und gesund zu halten. Und obwohl wir Ihr Engagement, unsere Arbeitsabläufe nicht zu unterbrechen, sehr schätzen, ist es nicht hilfreich, viele der von Ihnen angebotenen Schutzmechanismen auf freiwilliger Basis anzubieten.
Bitte, bitte, bitte fangen Sie an, die wichtigsten Sicherheitsfunktionen automatisch zu aktivieren, zumindest bei beliebten Open-Source-Projekten als Teil Ihrer Einführungsstrategie.
Das neue GitHub Advanced Security Code Scanning for GitHub Actions hätte die Betreuer des Projekts nx
auf die Script Injection-Schwachstelle aufmerksam machen können. Es ist jedoch weder standardmäßig aktiviert, noch werden die Betreuer gewarnt, dass sie sich für diesen Schutz entscheiden müssen.
Die vor langer Zeit geänderte Standardeinstellung für Nur-Lese-Berechtigungen für GitHub-Aktionen hätte das Auslösen des Veröffentlichungs-Workflows verhindert, aber diese Einstellung wird auf dem Standardwert der Organisation belassen, und die Betreuer werden nicht gewarnt, dass sie diese Einstellung ändern sollten.
Die Anforderung, dass Workflows, die von externen Mitarbeitern ausgelöst werden, immer von einem Betreuer genehmigt werden müssen, hätte zumindest einen menschlichen Eingriff als Teil der Angriffskette ausgelöst. Aber auch diese neue Vorgabe wurde nicht an bestehende Organisationen weitergegeben, und die Betreuer werden nicht gewarnt, dass sie diese Einstellung wirklich ändern sollten.
Das Anheften von Aktionen an ihren vollständigen Commit Sha ist schon seit Jahren eine Empfehlung. GitHub hat jedoch keine Werkzeuge zur Verfügung gestellt, um diesen Prozess zu vereinfachen, und obwohl die Richtlinie endlich eingeführt wurde, wurde sie wieder mit relativ geringem Trara eingeführt und die Betreuer werden nicht gewarnt, dass sie diese Einstellung wirklich ändern sollten. Auch Dependabot oder GitHub Advanced Security Code Scanning for Actions reichen keine Pull-Anfrage ein, um diese Aktionen festzulegen.
Dies war nicht der erste Angriff, bei dem der Auslöser pull_request_target
zum Einsatz kam. Ich würde mir wünschen, dass Workflows mit diesem Auslöser nicht automatisch aktiviert werden, sondern eine explizite Aktivierung durch den Besitzer mittels einer Gefahrenzonen-Aktion erfordern, die die Risiken klar benennt.
Also noch einmal: Bitte fangen Sie an, diese grundlegenden Sicherheitsfunktionen automatisch zu aktivieren und machen Sie die Einführung solcher Funktionen zu einem Teil der Einführung neuer Funktionen wie diesen.
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