Zurück zum Blog

Ist Go besser vor Supply-Chain-Angriffen geschützt als Node.js?

Ja, Go ist strukturell besser vor Supply-Chain-Angriffen geschützt als Node.js, vor allem weil go get keine Install-Skripte ausführt. Hier findest du die Argumentation mit Quellen und die Gegenbeispiele.

Ist Go besser vor Supply-Chain-Angriffen geschützt als Node.js?

Die meisten großen Supply-Chain-Angriffe der letzten zwei Jahre liefen nach demselben Muster ab. Ein Entwickler führte npm install aus, und eine Dependency, die er nie selbst ausgewählt hatte, startete Code auf seinem Rechner, noch bevor er eine einzige Zeile geschrieben hatte. npm lässt das bewusst zu und nimmt diese Entscheidung gerade zurück. Go hat das nie erlaubt. Dieser Beitrag zeigt, wie viel dieser eine Unterschied erklärt, wo Go wirklich sicherer ist und wo es denselben Risiken gegenübersteht wie Node. Jede Aussage ist mit einer Quelle belegt.

Kurzfassung

Go vs Node.js: Supply-Chain-Sicherheit im Überblick

AspektGo (Golang)Node.js (npm)
Codeausführung bei der InstallationKeine. go get/go build führen keine Paket-Skripte aus.preinstall/install/postinstall führen automatisch beliebigen Code aus.
Wann bösartiger Code läuftNur wenn er importiert und die Funktion aufgerufen wird.In dem Moment, in dem du installierst, bevor du eine Zeile schreibst.
IntegritätsgarantieChecksum-Transparency-Log auf Merkle-Tree-Basis (sum.golang.org). Manipulationen bleiben dauerhaft nachweisbar.Lockfile-Hashes plus neuere Provenance-Nachweise. Historisch schwächer.
VersionsauflösungMinimal Version Selection. Upgrades erfolgen explizit.Semver-Ranges (^, ~). Ein neuer bösartiger Patch kann automatisch aufgelöst werden.
Dependency-OberflächeGroße Standardbibliothek, weniger direkte Dependencies.Kultur winziger Module, ausufernde transitive Bäume.
Schwachstellen-Scansgovulncheck macht eine Reachability-Analyse und liefert deshalb weniger Fehlalarme.npm audit meldet den gesamten Baum, was zu Alert Fatigue führt.
Registry-ModellDezentral. Module sind Quell-URLs.Zentrale Accounts. Ein einziger Phishing-Treffer legt ein ganzes Portfolio offen.
Weiterhin anfällig fürGephishte Maintainer, Typosquats, Caching von Malware im Proxy.Alles oben Genannte plus Würmer über Install-Skripte.

Go liegt beim Standardverhalten und bei der Angriffsfläche vorn. Ein entschlossener Angreifer, der einen menschlichen Maintainer phisht, kommt aber in beiden Ökosystemen durch.

Warum bleibt Go von dem Angriff verschont, der npm am härtesten trifft?

Go hat keine Install-Skripte. Wenn du npm install ausführst, kann jedes Paket im transitiven Baum Lifecycle-Hooks registrieren (preinstall, install, postinstall). npm führt sie automatisch mit den Rechten deines Users aus, bevor du auch nur eine einzige Zeile ausgeführt oder gelesen hast (npm-Doku zu Scripts). GitHub hat Install-Skripte als die größte einzelne Angriffsfläche für Codeausführung im npm-Ökosystem bezeichnet (GitHub Security, 2025).

Go hat das bewusst weggelassen. Es gibt keine Build-Hooks. go get lädt den Quellcode herunter und verifiziert ihn, go build kompiliert ihn, und keiner der beiden Befehle führt Skripte aus, die ein Paket definiert. Eine vergiftete Go-Dependency liegt als reiner Quellcode da, bis dein Code sie importiert und die bösartige Funktion aufruft. Dieses Zeitfenster ist viel enger und leichter zu entdecken als Code, der bei jeder Installation für alle läuft.

So verhalten sich die beiden Befehle:

example.bashbash
# npm: the postinstall hook runs on every install, automatically
$ npm install left-pad
> [email protected] postinstall
> node ./scripts/setup.js   # <- arbitrary code, your privileges, right now

# go: nothing in the package gets to run during fetch or build
$ go get example.com/some/module
go: downloaded example.com/some/module v1.0.0   # source fetched, checksum verified, nothing executed

Wegen dieses Unterschieds blockiert npm v12, das im Juli 2026 erscheint, Install-Skripte standardmäßig, und pnpm hat das mit v10 bereits getan (npm-Doku zu Scripts). Das JavaScript-Tooling bewegt sich auf das Verhalten zu, das Go seit dem Launch hat.

Wie groß ist das Supply-Chain-Problem von npm in Zahlen?

npm ist mit Abstand das größte Ziel. Sonatype hat 2025 insgesamt 454.648 neue bösartige Pakete identifiziert. Damit stieg die kumulierte Zahl blockierter Pakete auf über 1,23 Millionen, ein Anstieg von 75 % gegenüber dem Vorjahr. Über 99 % dieser Open-Source-Malware lag auf npm (Sonatype 11th State of the Software Supply Chain, 2026). Im Malware-Index für Q4 2025 lag der Anteil bei 99,8 % der in diesem Quartal blockierten Malware.

Eine veröffentlichte Zahl bösartiger Go-Module gibt es überhaupt nicht. Sonatype, die OpenSSF und die meisten Anbieter führen Go in ihren Malware-Indizes nicht als eigenes Ökosystem, weil es zu wenige Vorfälle für einen Index gibt. Diese Lücke in den Daten sagt schon viel.

Wo 2025 die Open-Source-Malware zu finden war (Anteil neuer bösartiger Pakete nach Ökosystem):

ÖkosystemAnteil an der Open-Source-Malware 2025
npmÜber 99 %
Alle anderen (inkl. Go)*Unter 1 %

*Im Jahr 2025 wurden 454.648 neue bösartige Pakete identifiziert. Go wird nicht als eigenes Ökosystem geführt, weil es zu wenige Vorfälle für einen Index gibt. Quelle: Sonatype 11th State of the Software Supply Chain, 2026.

Was ist bei der npm-Wurmwelle 2025 und 2026 wirklich passiert?

Eine Serie sich selbst verbreitender Würmer machte aus einem bekannten Risiko einen Dauernotfall, und jeder einzelne davon nutzte Install-Skripte. npm hat schon seit Jahren vielbeachtete Vorfälle. 2018 versteckte event-stream einen Stealer für Bitcoin-Wallets in einer Dependency mit rund 8 Millionen Downloads. 2021 lieferte ua-parser-js nach einer Account-Übernahme Cryptominer aus. Seit 2025 folgen die Vorfälle aber direkt aufeinander.

DatumVorfallWas passiert ist
8. Sep. 2025qix gephisht18 Pakete gekapert, darunter chalk und debug. Rund 2,6 Mrd. wöchentliche Downloads betroffen.
Sep. 2025Shai-HuludErster npm-Wurm. Ein postinstall-Hook sammelte Zugangsdaten und schleuste sich pro Opfer selbst in rund 100 weitere Pakete ein.
24. Nov. 2025Shai-Hulud 2.0Wechsel zu preinstall, dazu das Löschen des Home-Verzeichnisses. Rund 796 Pakete, gefunden in 27 % der gescannten Cloud-Umgebungen.
31. März 2026axiosNordkoreanische Akteure manipulierten den Maintainer per Social Engineering. Ein postinstall-RAT löste in über 12.000 Projekten C2-Kontakt aus.
Juni 2026MiasmaUmging die Install-Skript-Sperre von npm mit der „Phantom Gyp“-Technik, einem impliziten node-gyp-Rebuild.

Die Kompromittierung von qix im September 2025 begann mit einer überzeugenden E-Mail zum Zurücksetzen der 2FA, verschickt von der gefälschten Domain npmjs.help. Der Angreifer übernahm den Account von Maintainer Josh Junon und veröffentlichte bösartige Versionen von 18 Paketen. Darunter waren chalk (~300 Millionen Downloads pro Woche) und debug (~358 Millionen), zusammen über 2,6 Milliarden wöchentliche Downloads. Die Payload war ein Crypto-Clipper, der im Browser lief, und sie war rund zwei Stunden lang aktiv.

Wenige Tage später folgte Shai-Hulud, der erste echte npm-Wurm. Bei der Installation sammelte seine bundle.js Zugangsdaten für npm, GitHub, AWS und GCP und ließ TruffleHog laufen, um Secrets abzugreifen. Danach nutzte er die gestohlenen npm-Tokens, um sich selbst in bis zu etwa 100 weitere Pakete jedes Opfers einzuschleusen. Die CISA gab eine Warnung heraus (CISA, 2025). Sonatype schreibt 171.740 bösartige Pakete den sich selbst replizierenden npm-Kampagnen innerhalb weniger Monate zu.

Shai-Hulud 2.0 (24. November 2025) verlagerte die Ausführung nach preinstall, um mehr Rechner zu erreichen. Er installierte die Bun-Runtime, um Node-basiertes Monitoring zu umgehen, und ergänzte einen destruktiven Fallback, der ein Home-Verzeichnis löschen konnte. Wiz fand betroffene Pakete in rund 27 % der gescannten Cloud-Umgebungen (Wiz, 2025).

2026 wurde klar, dass das Blockieren von Install-Skripten allein nicht reicht. Die Kompromittierung von axios (31. März 2026) begann nicht mit einem gephishten Passwort. Mit Nordkorea verbundene Akteure (geführt als UNC1069 / Sapphire Sleet) nahmen den Lead Maintainer mit einer gefälschten Firma, einem Slack-Workspace im passenden Branding und einem Teams-Call ins Visier, der einen RAT auf dem Rechner des Maintainers platzierte. Anschließend veröffentlichten sie bösartige axios-Versionen (über 100 Mio. wöchentliche Downloads) mit einem postinstall-RAT. StepSecurity erkannte in über 12.000 Projekten auffälligen C2-Kontakt (StepSecurity, 2026). Danach umging Miasma (Juni 2026) die kommende Install-Skript-Sperre von npm mit der „Phantom Gyp“-Technik. Das Paket liefert eine binding.gyp-Datei mit, und der implizite node-gyp-Rebuild von npm führt die Payload ohne deklariertes Skript aus.

Ist Go also ein Allheilmittel? Nicht ganz

Die Defaults von Go stoppen eine ganze Klasse von Angriffen, aber Angreifer haben Go trotzdem ein paar Mal ins Visier genommen. Die dokumentierten bösartigen Go-Module aus 2025 belaufen sich auf wenige Dutzend, verteilt auf eine Handvoll Kampagnen. Neben den Hunderttausenden bei npm ist das winzig. Der bekannteste Fall lohnt einen genaueren Blick, weil er zeigt, wie viel Aufwand ein Angreifer treiben muss, um am Design von Go vorbeizukommen.

Die boltdb-go/bolt-Backdoor wurde im Februar 2025 öffentlich, war aber schon im November 2021 platziert worden. Sie nutzte Typosquatting auf das beliebte BoltDB-Modul (github.com/boltdb/bolt), von dem Tausende Pakete abhängen und das bei Shopify und Heroku eingesetzt wurde, und enthielt eine Command-and-Control-Backdoor. Der Angreifer veröffentlichte die bösartige v1.3.1, ließ sie vom Go Module Mirror cachen und schrieb dann den Git-Tag um, sodass er wieder auf sauberen Code zeigte. Wer das Repo auf GitHub prüfte, sah sauberen Code, während der Proxy weiter die Backdoor auslieferte. Das hat funktioniert, aber nur durch das Ausnutzen eines Grenzfalls im Caching-System. Bei npm hätte ein Install-Hook dasselbe ohne diesen Aufwand erledigt (Socket, 2025).

2025 tauchten noch ein paar weitere Kampagnen auf. Im März gab es eine Welle von Typosquats namens hypert und layout mit Loader-Malware, die auf Entwickler im Finanzsektor zielte. Dazu kamen einige Module mit Disk-Wipern und ein Stealer für SSH-Zugangsdaten. Alle diese Fälle waren isoliert, und jeder brauchte einen Entwickler, der den falschen Importpfad eintippt. Keiner lief automatisch.

Wird ein bösartiges Modul gemeldet, entfernt das Go-Security-Team es aus dem Proxy, der dann 403 SECURITY ERROR zurückgibt, und nimmt es in die Go-Schwachstellendatenbank auf. Bei boltdb-go entfernte Google das Modul sowohl aus dem Proxy als auch von GitHub und erfasste es in der Schwachstellendatenbank. Außerdem verwies Google auf laufende Arbeiten an Capability-Analysen mit Capslock und an Abgleichen mit deps.dev. Die Schutzmechanismen von Go machen Angriffe deutlich teurer, garantieren aber keine Sicherheit, und das tut auch kein anderes Ökosystem.

Was macht Go strukturell sicherer?

Neben den fehlenden Install-Skripten trägt Go mit vier weiteren Designentscheidungen zum Vorsprung bei.

Die Checksum-Datenbank von Go ist ungewöhnlich stark. Deine go.sum hält SHA-256-Hashes aller Dependencies fest. sum.golang.org ist ein Transparency Log auf Merkle-Tree-Basis nach dem Vorbild von Certificate Transparency. Es speichert den Hash jeder Modulversion beim ersten Abruf durch irgendwen und behält ihn für immer (Go-Modulreferenz). Der go-Befehl prüft Inclusion- und Consistency-Proofs, bevor er irgendwelchem Code vertraut. Ein per Force-Push geänderter Git-Tag oder ein manipulierender Proxy scheitert deshalb mit einer deutlichen Fehlermeldung. Der Kryptograf Filippo Valsorda, der das Go-Security-Team bei Google geleitet hat, argumentiert, dass Go die beste Paketintegrität aller Sprach-Ökosysteme hat, weil jeder Client weltweit eine bestimmte Modulversion für immer zu denselben Bytes auflöst (Filippo Valsorda). Das Log hat eine Grenze. Es beweist Konsistenz, nicht dass der Code gut ist, und es hilft nur, wenn jemand es überwacht.

Minimal Version Selection bremst schlechte Releases. Go-Builds verwenden die niedrigste Version, die alle Anforderungen erfüllt, und Upgrades erfolgen explizit (MVS-Referenz). Mit den Ranges ^ und ~ von npm kann ein frisch veröffentlichter bösartiger Patch automatisch in einem Build landen. In Go verbreitet sich ein schlechtes neues Release erst dann zu abhängigen Projekten, wenn eine Person die Anforderung bewusst anhebt. Die Würmer rund um qix und Shai-Hulud waren genau auf das automatische Upgrade-Verhalten angewiesen, das MVS nicht hat.

govulncheck senkt mit Reachability-Analyse die Zahl der Fehlalarme. Der offizielle Scanner von Go prüft die kuratierte Schwachstellendatenbank unter vuln.go.dev und warnt nur, wenn dein Code das verwundbare Symbol tatsächlich aufruft (govulncheck, Go-Blog). npm audit meldet jede verwundbare Version irgendwo im Baum, egal ob du sie je erreichst, und Entwickler gewöhnen sich an, die Ausgabe zu ignorieren.

Es gibt keinen zentralen Account, dessen Übernahme ein ganzes Portfolio offenlegt. Go-Module werden über ihre Quell-URL identifiziert und verlassen sich damit auf die Account-Sicherheit von GitHub (oder GitLab). Bei npm legt ein einziger übernommener Account alles offen, was diesem Maintainer gehört. Dieser Unterschied ist ein Grund dafür, dass sich npm-Würmer so ausbreiten, wie sie es tun, während Go-Vorfälle begrenzt bleiben.

Die größere Standardbibliothek hilft ebenfalls. HTTP, JSON, Kryptografie und Templating gehören bei Go zum Lieferumfang, deshalb hat ein typisches Projekt weniger direkte Dependencies und weniger Maintainer, denen es vertrauen muss. Eine Studie von 2025 ergab allerdings, dass die Verstärkung pro Dependency bei Go (etwa 4,48x) nah an der von npm (etwa 4,32x) liegt. Ein Go-Paket zieht also nicht weniger transitive Dependencies nach als ein npm-Paket. Go liegt vorn, weil Projekte mit weniger direkten Dependencies starten, und das hält den Kreis der Leute klein, denen du vertraust.

Was die Defaults von Go nicht abdecken

Go schließt die größten Türen automatisch. Die folgenden Risiken betreffen jedes Ökosystem, auch Go, deshalb musst du sie selbst abdecken.

  • Ein gephishter Maintainer kommt an den Schutzmechanismen jedes Ökosystems vorbei. Wird der GitHub-Account eines Maintainers übernommen, kann der Angreifer ein bösartiges Release taggen, und die Checksum-Datenbank zeichnet es getreu auf, weil sie guten nicht von schlechtem Code unterscheiden kann. Ein Angriff nach dem Muster von axios funktioniert gegen jedes Ökosystem, deshalb stellt die Branche auf Hardware-Keys und Trusted Publishing um.
  • Du wählst deine Dependencies weiterhin über den Namen aus. Die Checksum-Prüfung von Go verhindert Manipulationen an einem Modul, das du ausgewählt hast, aber sie kann dich nicht davon abhalten, einen Typosquat zu wählen. Gleiche den Importpfad mit dem kanonischen Repo ab, bevor du eine Dependency hinzufügst.
  • Die Unveränderlichkeit des Proxys ist überwiegend ein Feature. Das Caching, das jedem Build identische Bytes garantiert, hat auch die boltdb-go-Backdoor erreichbar gehalten, nachdem der Git-Tag bereinigt war. Dieser Fall war selten, und der Entfernungsprozess des Go-Teams sowie die Schwachstellendatenbank decken ihn ab.
  • Die Defaults schützen die Installationszeit, nicht die Laufzeit. Der Vorteil von Go ist, dass beim Abrufen oder Bauen nichts läuft. Sobald du eine Dependency importierst und aufrufst, läuft sie mit deinen Rechten, genau wie in jeder anderen Sprache. Nicht vertrauenswürdigen Code zur Laufzeit in eine Sandbox zu stecken, ist in jedem Ökosystem ein eigenes Problem.
  • Lass den Schutz eingeschaltet. Der einzige selbst verschuldete Fehler ist, GOSUMDB=off pauschal zu setzen. Damit schaltest du die oben beschriebene Checksum-Prüfung ab. Lass sie an und beschränke GOPRIVATE nur auf echte interne Pfade.

Wie laufen beide Ökosysteme auf dieselben Lösungen zu?

Beide Ökosysteme führen dieselben Schutzmaßnahmen ein, weil die Schwachstelle in beiden die Menschen sind. Nach der Welle von 2025 kündigte GitHub verpflichtende 2FA mit FIDO/WebAuthn an, dazu kurzlebige, feingranulare Tokens und das Auslaufen der alten Classic Tokens. Außerdem treibt GitHub Trusted Publishing über OIDC für kryptografische Build-Provenance voran (GitHub Security, 2025). npm v12 (Juli 2026) blockiert Install-Skripte standardmäßig und bringt eine min-release-age-Wartezeit mit, sodass ein Paket, das nur zwei Stunden lang online ist, dich nie erreicht.

Diese Änderungen helfen. Aber axios hat gezeigt, wo sie nicht mehr greifen. Keine Token-Richtlinie stoppt einen Maintainer, auf dessen Laptop ein RAT läuft. Das hätten nur Hardware-FIDO2-Keys zusammen mit Installationen mit geprüfter Provenance und Wartezeit geschafft. Beide Communitys lernen gerade, dass Angreifer eher den Maintainer angreifen als das Tooling. Auch hier hat Go einen Vorteil. Selbst wenn ein Maintainer kompromittiert ist, entsteht weniger Schaden, weil bei der Installation nichts läuft.

Was solltest du jetzt tun?

Die Schritte hängen von deinem Stack ab.

Wenn du Go schreibst:

  1. Setze GOSUMDB=off oder GONOSUMCHECK nie pauschal. Beschränke GOPRIVATE eng auf echte interne Pfade.
  2. Committe go.sum und baue mit -mod=readonly.
  3. Führe govulncheck ./... in der CI als Gate mit Reachability-Analyse aus.
  4. Prüfe neue Dependencies auf Typosquats. Gleiche Importpfade mit dem kanonischen Repo ab, bevor du sie hinzufügst.
  5. Überwache kritische Dependencies mit Socket oder deps.dev auf neue Releases.

Wenn du Node schreibst:

  1. Aktualisiere auf npm 11.16.0+ und setze ignore-scripts=true, mit einer Allowlist (etwa @lavamoat/allow-scripts) für die wenigen Pakete, die wirklich Skripte brauchen.
  2. Nutze npm ci mit eingefrorenem Lockfile, pinne exakte Versionen und setze eine min-release-age-Wartezeit von 3 bis 7 Tagen, damit dich zweistündige Kompromittierungen nie erreichen.
  3. Setze auf Trusted Publishing (OIDC) und Hardware-FIDO2-Keys. Verlass dich beim Veröffentlichen nicht auf TOTP.
  4. Nutze echte Software Composition Analysis (Socket, Snyk) mit Verhaltenserkennung, nicht nur npm audit.
  5. Registriere deine internen Paketnamen vorsorglich öffentlich, um Dependency Confusion zu verhindern.

Häufig gestellte Fragen

Ist Go bei der Supply-Chain-Sicherheit wirklich sicherer als Node.js?

Ja, strukturell. Der Hauptgrund ist, dass go get und go build keine Skripte zur Installationszeit ausführen. Damit fällt der preinstall/postinstall-Angriffsvektor weg, hinter dem fast jeder größere npm-Wurm aus 2025 und 2026 steckt. Über 99 % der Open-Source-Malware von 2025 tauchten auf npm auf (Sonatype, 2026). Go ist sicherer, aber nicht immun.

Was ist der größte Unterschied zwischen der Sicherheit von Go und npm?

Codeausführung bei der Installation. Bei npm install führt npm automatisch beliebige Paket-Skripte mit deinen Rechten aus, und zwar für jedes Paket im Baum. Go hat überhaupt keine Build-Hooks, deshalb tut eine bösartige Dependency nichts, bis dein Code sie importiert und aufruft. Deshalb blockiert npm v12 Install-Skripte jetzt standardmäßig, so wie Go es schon immer gehandhabt hat.

Gab es in Go schon einmal einen Supply-Chain-Angriff?

Ja. Die boltdb-go-Backdoor nutzte Typosquatting auf BoltDB und lieferte drei Jahre lang über den Modul-Cache von Go eine Backdoor für Fernzugriff aus (Socket, 2025). Eine hypert/layout-Kampagne verbreitete 2025 mindestens sieben Typosquats mit Loader-Malware. Diese Vorfälle sind real, aber selten, und bösartige Module werden nach einer Meldung aus dem Proxy entfernt.

Was ist die Go-Checksum-Datenbank und warum ist sie wichtig?

sum.golang.org ist ein Transparency Log auf Merkle-Tree-Basis. Es speichert den Hash jeder Modulversion dauerhaft, sobald diese Version zum ersten Mal auftaucht. Der go-Befehl prüft diese Proofs, bevor er Code vertraut, sodass Manipulationen oder ein umgeschriebener Git-Tag mit einer deutlichen Fehlermeldung scheitern (Go-Modulreferenz). Jeder Client bekommt für eine bestimmte Version identische Bytes. Das ist die stärkste Integritätsgarantie im verbreiteten Paketmanagement.

Löst das Blockieren von npm-Install-Skripten das Problem?

Es hilft sehr, löst aber nicht alles. Der axios-Angriff nutzte einen postinstall-RAT, nachdem der Maintainer per Social Engineering manipuliert worden war, und die Miasma-Kampagne umging die Skript-Sperre über einen impliziten node-gyp-Rebuild. Blockierte Skripte zusammen mit Hardware-FIDO2-Keys, einer Wartezeit für neue Releases und Provenance-Prüfung schließen den Großteil der Lücke. Ein gephishter Maintainer kommt aber trotzdem an jeder einzelnen Maßnahme vorbei.

Sollte ich allein wegen der Sicherheit von Node zu Go wechseln?

Sicherheit spricht für Go, aber die meisten Teams wählen eine Sprache nach allem, was sie mitbringt: Nebenläufigkeit, Recruiting, Ökosystem und wie schnell sie ausliefern können. Go ist eine starke Backend-Sprache und zugleich die strukturell sicherere Wahl gegen Supply-Chain-Angriffe. Wenn du Go ohnehin schon in Betracht ziehst, sind die sichereren Defaults ein weiterer Grund, es zu lernen.

Quellen

In diesem Beitrag zitierte Primärquellen (zuletzt geprüft am 29. Juni 2026):

Schreib Go wie ein Senior Engineer

Interaktive Lektionen im Browser. Die ersten sind kostenlos.

Kostenlose Lektion testenOder kostenloses Konto erstellen