Repojacking und warum Go-Modulpfade Übernahmeziele sind

Die „php2shell“-Patches (CVE-2026-109618 und CVE-2026-109619) für PHP am Ende des Lebenszyklus (EOL) sind nun verfügbar. Da die Antworten des Vertriebs aufgrund der hohen Nachfrage derzeit langsamer als gewöhnlich ausfallen, ist der schnellste Weg zu den gepatchten Paketen der Online-Kauf von ELS für Runtimes (wird in einem neuen Tab geöffnet). Lesen Sie die FAQ zu den Patches

Gehen Sie direkt zu einer KI-Zusammenfassung dieses Blogbeitrags

  • Fasse diesen Beitrag mit Perplexity zusammen
  • Fasse diesen Beitrag mit Gemini zusammen

Wichtigste Erkenntnisse

  • Go identifiziert ein Paket anhand seines Speicherorts und nicht anhand eines Namens, der jemandem gehört. Daher kann ein abgelaufener GitHub-Benutzername schon für sich genommen zu einem Problem in der Lieferkette werden.
  • Die Prüfsummen-Datenbank garantiert, dass jeder denselben Code für eine bestimmte Version erhält – nicht jedoch, dass die Version von einer Person stammt, der Sie vertrauen.
  • GitHub legt beliebte Namespaces still, doch Downloads, die über den Modul-Mirror von Go bereitgestellt werden, werden nicht als die Klone erfasst, die diesen Schutz auslösen.
  • Die Pfade, die überprüft werden müssen, sind die kleinen transitiven, die niemand liest.

Im Dezember 2023 suchten Forscher von VulnCheck auf GitHub nach Go-Repositories, die sich in einem wiederherstellbaren Zustand befanden, und die Zahl fiel höher aus, als die meisten Menschen vermuten würden. Über 15.000. Mehr als 9.000 wurden durch eine Änderung des GitHub-Benutzernamens offengelegt, weitere über 6.000 durch die Löschung von Konten. Zusammen umfassen diese Repositories mehr als 800.000 Go-Modulversionen.

Dafür sind weder gestohlene Zugangsdaten noch eine kompromittierte Build-Pipeline erforderlich. Es reicht aus, dass ein Konto abläuft und jemand dies bemerkt, bevor der ursprüngliche Inhaber es tut.

Diese Zählung ist mittlerweile schon ein paar Jahre alt, und niemand hat eine neue veröffentlicht. Der dahinterstehende Mechanismus hat sich jedoch nicht geändert, und der Grund, warum er in Go funktioniert und fast nirgendwo sonst, liegt darin, wie Go überhaupt definiert, was ein Paket ist.

Warum die Identität eines Go-Pakets eher ein Ort als ein Name ist

Die meisten großen Registries führen ein Verzeichnis der Eigentumsverhältnisse. npm weiß, wer axios veröffentlichen darf. PyPI weiß, wer eine neue Version von requests hochladen darf. Maven Central überprüft einen Namespace, bevor jemand eine groupId darunter beanspruchen kann.

In Go dient ein Pfad gleichzeitig als Adresse.

„github.com/someuser/somelib“ ist kein bei einer Go-Registrierungsstelle registrierter Name. Es handelt sich um einen Modulpfad, der der Toolchain mitteilt, wo sie suchen soll, und wer auch immer diesen Speicherort kontrolliert, bestimmt, welche Versionen von dort aus als Nächstes bereitgestellt werden können. Wenn das dahinterstehende Konto verschwindet und jemand anderes den Benutzernamen beansprucht, verweist der Importpfad in Ihrer `go.mod`-Datei nun auf dessen Code.

Dies ist etwas ganz anderes als die Kampagnen zur Kontoübernahme, die in letzter Zeit für Schlagzeilen sorgen, wie zum Beispiel PolinRider. Diese Kampagne betraf ebenfalls Go-Module im Jahr 2026, doch der Mechanismus ist ein anderer. Die Angreifer übernahmen damals noch aktive Konten und änderten in einigen Fällen Git-Tags, um ihre Machenschaften zu verschleiern. Repojacking verläuft unauffälliger und ist in gewisser Weise einfacher, da kein Einbruch erforderlich ist. Sobald ein Konto nicht mehr existiert, gibt es nichts mehr zu verteidigen.

Die Modulauflösung von Go ist elegant, und das sollte man erwähnen, bevor man darauf eingeht, was daran nicht stimmt. „go get github.com/user/lib“ löst standardmäßig über den Modul-Proxy auf, erfasst eine Version und schreibt einen Hash. Kein Konto, keine Einreichung in die Registry, keine Veröffentlichungspipeline. Man pusht ein korrekt benanntes Versions-Tag, und schon existiert die Version – ganz ohne separaten Veröffentlichungsschritt dazwischen.

Das funktioniert, weil der Importpfad die maßgebliche Quelle ist. Der Pfad teilt der Toolchain mit, wo sie suchen muss, und kein zweites System erfasst, wer dort Code ablegen darf.

Vergleichen Sie, welche Informationen die einzelnen Registries tatsächlich über ein Paket haben.

Registrierung Identität ist Eigentumsverzeichnis Nach der Aufgabe wiedererlangbar
npm Ein eingetragener Name Ja, mit dem Konto verknüpft Nein, die Namen bleiben reserviert.
PyPI Ein eingetragener Name Ja, mit dem Konto verknüpft Nur im Rahmen eines formellen Verfahrens
Maven Central Ein Namensraum, der an eine verifizierte Domain oder ein Quell-Repository gebunden ist Ja, Namensraum überprüft Ja, wenn die Domain abläuft
crates.io Ein eingetragener Name Ja, mit dem Konto verknüpft Nein, die Namen bleiben reserviert.
Packagist Ein eingetragener Name Ja, mit dem Konto verknüpft Nein, die Namen bleiben reserviert.
Go-Module Ein VCS-Standort Keine Ja, sobald der Standort frei wird

Maven hat seine eigene Variante dieses Problems in Form von abgelaufene Domains, wie es die MavenGate-Studie bereits im Januar 2024 beschrieben hat. Gruppen-IDs werden aus Domains abgeleitet, sodass eine abgelaufene Domain den damit verbundenen Namensraum freigibt.

Auch bei Packagist gab es einen dokumentierten Fall. Bei einem Vorfall im Jahr 2022 hat ein Forscher das GitHub-Repo hinter einem Packagist-Paket gekapert und brachte Malware zur Veröffentlichung, da Packagist GitHub nach Releases durchsuchte, ohne dass ein separater Veröffentlichungsschritt erforderlich war. Diese Sicherheitslücke wurde inzwischen geschlossen, und nach dem Vorfall mit der Umschreibung des „Laravel-Lang“-Tags im Mai 2026 ging Packagist noch einen Schritt weiter und stabile Versionen unveränderlich gemacht– im Mai angekündigt und im Juli aktiviert. Es lohnt sich jedoch, klarzustellen, was dadurch behoben wird. Unveränderliche Versionen verhindern, dass jemand die Git-Referenz einer veröffentlichten Version verschiebt. Sie tun jedoch nichts dagegen, wenn jemand einen aufgegebenen Namensraum beansprucht und darunter etwas Neues veröffentlicht.

Für Go ist dieses zweite Szenario die Standardkonfiguration für jedes Modul, das unter einem persönlichen GitHub-Konto gehostet wird. Das Sicherheitsteam von GitHub nannte Go in seinem Beitrag aus dem Jahr Beitrag aus dem Jahr 2024 zum Thema „Repojacking“, neben GitHub Actions und Git-Submodulen, und seine Empfehlung für diese beiden lautet, an einen bestimmten Commit zu binden. Go verfügt über eine Integritätsschicht, die diese beiden nicht haben, da Modulversionen anhand von go.sum und standardmäßig anhand der öffentlichen Prüfsummen-Datenbank authentifiziert werden. Und genau hier wird die Sache interessanter, als es zunächst den Anschein hat.

Es gibt auch eine sich langsamer entwickelnde Variante dieses Risikos. Ein großer Teil der Open-Source-Komponenten, die irgendwo im Produktionscode enthalten sind, wurde seit Jahren nicht mehr aktualisiert, und gerade bei ruhenden Projekten kommt es häufig vor, dass die Betreuer irgendwann ihr Konto löschen oder die Domain verfallen lassen. In den meisten Ökosystemen ist das ein Problem bei der Patch-Verwaltung. Bei Go ist es zudem eine Angriffsfläche für Übernahmen.

So funktioniert Repojacking bei einem Importpfad

Zwei Ereignisse auf Kontoebene geben einen GitHub-Pfad frei. Durch das Löschen eines Kontos wird der Benutzername freigegeben, und durch das Ändern eines Benutzernamens wird der alte freigegeben. In beiden Fällen bleibt „github.com/olduser/lib“ unbesetzt, und wer diesen Benutzernamen als Nächstes registriert, kann ein Repository unter dem entsprechenden Namen neu anlegen und den Pfad übernehmen. Das Löschen eines einzelnen Repositorys unter einem noch bestehenden Konto führt nicht dazu, da niemand anderes ein Repository innerhalb Ihres Kontos erstellen kann.

GitHub schützt zwar davor, doch dieser Schutz ist enger gefasst, als die meisten Menschen annehmen. Durch die Stilllegung eines Namespace wird eine Kombination aus Eigentümer und Repository-Name dauerhaft gesperrt, sodass sie nicht wiederverwendet werden kann. Dies gilt für Repositorys, die in der Woche vor der der Umbenennung oder Löschung sowie alle, die eine auf dem GitHub Marketplace gelistete Aktion enthalten.

Das bedeutet, dass der Schutz die Pakete abdeckt, um die sich ohnehin schon alle Sorgen machen, und den „Long Tail“ unberücksichtigt lässt.

 

Speziell bei Go erweist sich dieser „Long Tail“ als enorm, und dieselbe Untersuchung, die diese über 15.000 Repositorys ermittelt hat, hat auch den Grund dafür aufgezeigt. Der Modul-Mirror von Go ruft ein Repository einmal ab und stellt diese Kopie anschließend allen anderen zur Verfügung. Ein Modul kann hinter Tausenden von „go get“-Aufrufen stehen, ohne dass diese über den Proxy bereitgestellten Downloads auf GitHub als Klone registriert werden. Daher kann eine stark genutzte Bibliothek immer noch unterhalb der Klon-Schwelle bleiben, die andernfalls ihren Namespace schützen würde. Bei einer gewöhnlichen Go-Bibliothek, die weder eine GitHub Action ist noch auf dem Marketplace steht, unterschätzt die Klonanzahl die nachgelagerte Nutzung erheblich.

Eine Utility-Bibliothek mit 40 Klonen pro Woche, die transitiv in einige hundert Projekte importiert wird, liegt ohnehin deutlich unter der Schwelle. Das sind die Pfade, die tatsächlich überprüft werden müssen, und es sind auch die Pfade, die niemand liest, da sie vier Ebenen tief im Abhängigkeitsbaum eines anderen landen.

Die Stilllegung wird zum Zeitpunkt der Umbenennung oder Löschung des Accounts bewertet und nicht fortlaufend. Ein Repository, das vor zwei Jahren beliebt war und seitdem inaktiv ist, hat möglicherweise in der entscheidenden Woche den Schwellenwert nicht erreicht. Da es weder eine API zur Überprüfung noch eine öffentliche Liste gibt, besteht die einzige Möglichkeit darin, zu versuchen, das Repository zu erstellen, und abzuwarten, ob GitHub meldet, dass der Name stillgelegt wurde und nicht wiederverwendet werden kann.

Warum die Prüfsummen-Datenbank keine Garantie für eine neue Version bieten kann

Die Prüfsummen-Infrastruktur von Go ist wirklich gut – besser als die der meisten anderen Ökosysteme. Genau zu wissen, was sie garantiert und wo diese Garantie endet, macht den Unterschied zwischen dem Gefühl, abgesichert zu sein, und tatsächlicher Absicherung aus.

sum.golang.org führt ein öffentlich überprüfbares Protokoll der Modul-Hashes, das nur um neue Einträge erweitert werden kann. Wenn bei einem Build eine öffentliche Modulversion aufgelöst wird, die noch nicht in go.sum enthalten ist, sucht die Toolchain diesen Hash im Protokoll, bevor sie ihn lokal speichert, sodass der erste Download nicht ungeprüft bleibt. Spätere Builds vergleichen die Daten mit den bereits gespeicherten Einträgen, und „go mod verify“ überprüft, ob die Kopien in Ihrem lokalen Modul-Cache seit dem Herunterladen nicht verändert wurden.

All diese Mechanismen erfüllen eine Aufgabe sehr gut: Sie sorgen dafür, dass jeder, der nach example.com/[email protected] fragt, identische Bytes erhält – heute und auch in fünf Jahren. Veröffentlicht man unterschiedliche Inhalte in einer Version, die bereits gespeichert wurde, wird die Diskrepanz deutlich sichtbar.

Beim „Repojacking“ wird eine gespeicherte Version niemals verändert. Der Angreifer veröffentlicht eine brandneue Version oder einen völlig neuen Pfad, und die Prüfsummen-Datenbank tut genau das, wofür sie geschaffen wurde. Bei einer wirklich neuen Version kann der vom Angreifer bereitgestellte Inhalt zum gespeicherten Inhalt für dieses Modul und diese Version werden, der von diesem Zeitpunkt an für alle nachgelagerten Nutzer originalgetreu authentifiziert wird. Der Hash ist echt. Der Protokolleintrag ist echt. Nichts in beiden deutet darauf hin, dass der Code von dem Betreuer stammt, dem Sie ursprünglich vertraut haben.

 

Szenario Vorheriger Hash für diese Version Übernahme erkannt
Aufgezeichnete Fassung mit neuen Inhalten erneut veröffentlicht Ja Ja, die Prüfsummen stimmen nicht überein
Neue Nebenversion eines gekaperten Pfads Nein, brandneue Version Nein
Nach einer Übernahme wurde eine neue Abhängigkeit hinzugefügt Nein Nein
Die transitive Abhängigkeit hat den Übernahme-Punkt überschritten Nein, brandneue Version Nein

Wenn Sie eine Abhängigkeit aktualisieren oder eine neue hinzufügen, kann die Toolchain nachweisen, dass es sich um dieselben Bytes handelt, die auch alle anderen erhalten. Das ist jedoch nicht dasselbe wie der Nachweis, dass sie in Ihren Build gehören.

Der Modul-Proxy unter proxy.golang.org hilft hier – wenn auch nur in begrenztem Umfang. Der Mirror speichert bereits abgerufene Versionen und kann diese auch dann noch bereitstellen, wenn sie im Upstream nicht mehr vorhanden sind. So bleibt eine vor der Übernahme abgerufene Version verfügbar und unverändert, selbst wenn das Repository später gelöscht oder ersetzt wird. Das ist ein echter Sicherheitsvorteil. Er gilt jedoch nur für Versionen, die bereits vor der Übernahme zwischengespeichert wurden, und sagt nichts über die nächste Version aus.

Was bleibt, ist die Frage, die keine Prüfsumme beantworten kann: ob der Inhalt, der bei der ersten Auflösung angezeigt wird, überhaupt vertrauenswürdig ist. Die Überprüfung eines Moduls vor dessen Auflösung und dessen Neuaufbau aus dem Quellcode zum Vergleich mit dem, was der Pfad bereitgestellt hat, ist eine andere Kontrollmaßnahme, die früher in der Abfolge erfolgt. Das ist die Ebene SecureChain für Go vor dem Proxy hinzufügt.

Vanity-Importpfade eröffnen einen zweiten Weg

„Repojacking“ in Bezug auf GitHub-Benutzernamen ist die Variante, die einen Namen erhalten hat und auf der einige Forschungsergebnisse basieren. Die Variante, die weitaus weniger Beachtung findet, betrifft benutzerdefinierte Domains.

Go unterstützt benutzerdefinierte Importpfade über HTML-Meta-Tags. Bei der Auflösung von example.com/mylib wird die Toolchain an https://example.com/mylib?go-get=1 weitergeleitet, wo ein „go-import“-Meta-Tag mit dem tatsächlichen VCS-Speicherort zurückgegeben wird, dem die Toolchain dann folgt. Auf diese Weise funktioniert golang.org/x/… und so veröffentlicht ein Unternehmen Module unter seiner eigenen Domain.

Die Art des Sicherheitslochs liegt auf der Hand, vor allem, weil ein Angreifer dafür nicht besonders clever sein muss. Wenn die Domain abläuft, kontrolliert derjenige, der sie als Nächstes registriert, alle darunter liegenden Modulpfade und kann diese Pfade nach Belieben umleiten. Hier gibt es keinen Schwellenwert für die Anzahl der Klone, keine Stilllegung von Namespaces und GitHub ist überhaupt nicht involviert.

Kleine Beratungsfirmen, gescheiterte Start-ups, Open-Source-Projekte von Einzelpersonen – das ist das Risiko. Eine abgelaufene Domain lässt sich zudem günstiger und unauffälliger erwerben als ein GitHub-Benutzername, der bereits eine Vorgeschichte hat.

go list -m -f ‘{{.Path}}’ all \
  | grep -v ‘^github.com/\|^golang.org/\|^gopkg.in/’ \
  | cut -d/ -f1 | sort -u

Damit erhalten Sie alle nicht offensichtlichen Hosts, von denen aus Ihr Build aufgelöst wird. Finden Sie heraus, wer die jeweiligen Domains verwaltet, und behalten Sie den Registrierungsstatus im Auge, denn eine Domain, deren Laufzeit bald abläuft oder die einfach nur verlassen wirkt, ist eine Abhängigkeit mit einer begrenzten Gültigkeitsdauer.

Überprüfung Ihrer Modulpfade auf Übernahme-Risiken

Zwei Überprüfungen, beide schnell erledigt. Führen Sie beide für jedes Go-Repository Ihrer Organisation durch, nicht nur für den Flaggschiff-Dienst, den ohnehin schon jeder im Blick hat.

Markieren Sie zunächst die URLs von GitHub-Repositorys, die keine „Live-Repository“-Antwort mehr zurückgeben.

go list -m -f ‘{{.Path}}’ all | grep ‘^github.com/’ \
  | cut -d/ -f1-3 | sort -u \
  | while read p; do
  printf ‘%s %s\n’ “$(curl -s -o /dev/null -w ‘%{http_code}’ “https://$p”)” “$p”
done | grep -v ‘^200’

Ein 404-Fehler ist ein Signal mit hoher Priorität, das darauf hinweist, dass der Pfad nicht mehr öffentlich verfügbar ist – es lohnt sich, dies zu überprüfen, bevor man davon als bestätigtes Repo-Jacking-Risiko ausgeht, da es auch bedeuten kann, dass das Repository privat geschaltet wurde. Ein 301-Fehler bedeutet in der Regel eine Umbenennung oder eine Kontoversetzung, und die Überprüfung folgt bewusst keinen Weiterleitungen, sodass der angezeigte Status dem tatsächlichen Zustand entspricht. Sobald ein Angreifer einen Pfad zurückerobert hat, kehrt die Überprüfung zum Status 200 zurück; somit wird das Zeitfenster vor einer Übernahme erfasst und nicht erst danach.

 

Dann schau dir an, was unter den Wegen, die zum Ziel führen, auf der Strecke geblieben ist.

go list -m -u all | grep ‘\[‘

Dadurch werden Module gekennzeichnet, für die neuere Versionen verfügbar sind – was eher ein Ausgangspunkt als eine Antwort ist. Bei einem Modul, das bereits mehrere Versionen zurückliegt, während der Upstream-Entwickler weiterhin neue Versionen veröffentlicht, lohnt es sich, einen Abgleich mit der tatsächlichen Aktivität im Repository vorzunehmen.

Führen Sie die 404-Prüfung in CI wöchentlich durch, anstatt sie als einmalige Überprüfung zu betrachten. Ein Account, der heute eines dieser Repositorys besitzt, kann im nächsten Monat gelöscht oder umbenannt werden, und die Zeitspanne, bevor jemand den alten Benutzernamen beansprucht, ist die kostenlose Warnung, die Sie erhalten.

Was man tatsächlich mit einem Modul tun soll, dessen Upstream-Entwickler endgültig verschwunden ist, ist eine schwierigere Frage als dessen Auffinden. Die Übernahme des Codes bedeutet, dass Ihr Team nun für dessen CVEs verantwortlich ist, und die meisten Unternehmen, die diesen Weg einschlagen, stellen dafür kein Personal bereit. Das Backportieren von Fehlerbehebungen in Code, von dem sich der Upstream-Betreuer abgewendet hat, ist ein eng gefasstes Fachgebiet, das sich eher auf Regressionstests und Verhaltenskompatibilität als auf neue Funktionen konzentriert – was in der Regel der Grund dafür ist, dass es außerhalb des Zuständigkeitsbereichs eines Produktteams liegt.

Was Sie an Ihren Go-Builds ändern sollten

Go verfügt weder über einen Lebenszyklus-Hook im Stil von npm noch über ein Äquivalent zu „postinstall“, sodass das Herunterladen einer Abhängigkeit einem Angreifer keinen kostenlosen Ausführungszugang verschafft. Das ist ein echter Vorteil gegenüber npm und PyPI.

Dieser Vorteil hat jedoch seine Grenzen. Code in einem Go-Modul wird letztendlich dennoch ausgeführt, und zwar immer dann, wenn etwas, das ihn importiert, kompiliert, getestet oder ausgeführt wird – üblicherweise durch eine init()-Funktion, die beim Start aufgerufen wird. Der automatische Auslöser zum Zeitpunkt der Installation entfällt. Der Codepfad bleibt jedoch bestehen, was ein anderes Problem darstellt und nicht unbedingt ein geringeres.

Wo Sie anfangen sollten, hängt davon ab, wo Sie bereits stehen. Wenn die Modulpfade noch nie überprüft wurden, führen Sie diese Woche die 404-Prüfung für jedes Repository durch, denn eine Stunde Arbeit liefert eine konkrete Liste, auf deren Grundlage Sie weiterarbeiten können. Wenn Ihre Abhängigkeiten Module unter persönlichen GitHub-Konten enthalten, verpacken Sie diese mit `go mod vendor` und committen Sie das Ergebnis. Dadurch werden die geprüften Inhalte der Abhängigkeiten in Ihr eigenes Repository übernommen, sodass Builds, die das `vendor`-Verzeichnis verwenden, diese Versionen niemals von einem Pfad abrufen, der in andere Hände gelangen könnte.

Wenn Sie Module aus benutzerdefinierten Domains auflösen, überprüfen Sie den Registrierungsstatus jeder einzelnen Domain, da eine abgelaufene Vanity-Domain eine umfassendere Übernahme darstellt als ein einzelner Benutzername und keinerlei Schutzschwelle aufweist. Wenn Sie GOPRIVATE oder GONOSUMDB verwenden, prüfen Sie die Muster sorgfältig. GONOSUMDB schließt übereinstimmende Module von der Überprüfung anhand der Prüfsummen-Datenbank aus, und GOPRIVATE fungiert als Standard für diesen Ausschluss, sofern Sie ihn nicht überschreiben. Daher führt ein weiter gefasster Platzhalter als beabsichtigt dazu, dass die Überprüfung anhand der Prüfsummen-Datenbank stillschweigend für mehr Module deaktiviert wird, als Sie eigentlich ausnehmen wollten. Und wenn Go in Ihrer Organisation neben npm, PyPI, Maven oder crates.io zum Einsatz kommt, legen Sie die Richtlinie einmalig für alle gemeinsam fest, denn Angreifer agieren über Ökosysteme hinweg, und die gute Absicherung eines einzelnen Systems verlagert das Problem lediglich an eine andere Stelle.

All dies ist keine einmalige Lösung. Ein Modul, das heute sicher ist, weil sein Betreuer noch aktiv ist, bleibt nicht zwangsläufig auch weiterhin sicher.

Das Risiko hängt stark davon ab, welcher Teil Ihres Projekts unter Unternehmenskonten und welcher unter privaten Konten verwaltet wird. Ein Go-Dienst, der hauptsächlich auf golang.org/x, den wichtigsten Cloud-SDKs und CNCF-Projekten basiert, ist in der Regel weniger von diesem speziellen Problem betroffen. Ein Dienst, der bereits 2019 sechs von einzelnen Entwicklern betreute Utility-Bibliotheken eingebunden hat, steht vor einer echten Herausforderung – und nur durch die Durchführung des Audits können Sie herausfinden, welche Abhängigkeiten besondere Aufmerksamkeit erfordern.

Wo SecureChain für Go zum Einsatz kommt

Die oben genannten Prüfungen verhindern eine Übernahme nicht. Sie zeigen Ihnen, wo Sie angreifbar sind, was zwar nützlich ist, aber nicht mit Prävention gleichzusetzen ist. Die verbleibende Lücke besteht darin, zu entscheiden, ob eine authentifizierte neue Modulversion überhaupt vertrauenswürdig ist, anstatt nur zu bestätigen, dass alle dieselben Bytes erhalten haben – und genau das leistet SecureChain für Go genau dafür entwickelt wurde. Es kompiliert Module aus dem Quellcode neu, überprüft sie beim Abruf und patcht bekannte Schwachstellen auch dann weiter, wenn der Upstream eines Moduls nicht mehr aktiv ist. Die Produktseite enthält weitere Details, und der Newsletter von TuxCare steht zur Verfügung, falls Sie lieber die neuesten Entwicklungen in der Go-spezifischen Supply-Chain-Forschung im Blick behalten möchten.

FAQ

Was ist „Repojacking“?

Die Rückgewinnung eines Quell-Repository-Pfads, von dem ein Projekt weiterhin abhängt – meist nachdem das ursprüngliche Konto gelöscht oder umbenannt wurde. Da in den Abhängigkeitsdateien weiterhin auf diesen Pfad verwiesen wird, führt Code, der an dem zurückgewonnenen Speicherort veröffentlicht wird, zu Builds, die auf dem ursprünglichen Repository basieren.

Warum ist Go besonders anfällig für Repojacking?

Go identifiziert Module anhand ihres VCS-Pfads und nicht anhand eines registrierten Namens mit einem Eigentumsvermerk. Es gibt kein Registrierungs-Konto, das „github.com/user/lib“ führt; sobald der zugrunde liegende Kontoname verfügbar wird, kontrolliert derjenige, der ihn beansprucht, den Modulpfad.

Verhindert die Go-Prüfsummen-Datenbank „Repojacking“?

Nicht von sich aus. Es gewährleistet, dass jeder, der eine bestimmte Modulversion herunterlädt, identische Inhalte erhält – auch beim ersten Download, wenn der Hash im öffentlichen Protokoll nachgeschlagen wird. Was es jedoch nicht feststellen kann, ist, ob eine brandneue Version, die über einen gekaperten Pfad veröffentlicht wurde, vertrauenswürdig ist, da eine tatsächlich neue Version, die über diesen Pfad veröffentlicht wurde, zu dem gespeicherten Inhalt werden kann, anhand dessen alle nachgelagerten Nutzer die Authentifizierung vornehmen.

Verhindert GitHub die Übernahme von Repository-Namespaces?

Teilweise, und zwar hauptsächlich bei beliebten Repos. Bei der Namespace-Stilllegung wird eine Kombination aus Eigentümer und Repo-Name gesperrt, wenn das Repo in der vorangegangenen Woche mehr als 100 Klone oder mehr als 100 Verwendungen in GitHub Actions hatte oder eine im Marketplace gelistete Aktion enthält. Kleinere Projekte liegen unter dieser Schwelle, und ihre Namespaces können weiterhin beansprucht werden. Für Go ist das Klonkriterium noch weniger streng, da der Modul-Mirror Tausende von Downloads bedienen kann, ohne dass dabei Klone entstehen.

Wie finde ich Go-Abhängigkeiten, die möglicherweise wiederverwendet werden können?

Listen Sie die Modulpfade mit dem Befehl „go list -m -f ‚{{.Path}}‘ all“ auf und prüfen Sie anschließend, ob die URL jedes Repositorys weiterhin eine gültige Antwort liefert. Ein 404-Fehler bei einem Pfad, von dem Ihr Build abhängt, muss näher untersucht werden, da dies in der Regel bedeutet, dass das Upstream-Repository nicht mehr existiert – es kann aber auch bedeuten, dass es nun privat ist. In jedem Fall lohnt es sich, diesen Pfad zu überprüfen, bevor Sie davon ausgehen, dass er sicher ist, und zwar nicht nur einmal, sondern in regelmäßigen Abständen.

Schützt „Vendoring“ vor „Repojacking“?

Ja, für Abhängigkeiten, die bereits in Ihr Vendor-Verzeichnis übertragen wurden. Beim Vendoring werden die Inhalte der Abhängigkeiten in Ihr Repository kopiert, und der Vendor-Modus von Go greift während der Kompilierung nicht auf das Netzwerk zu. Neue Abhängigkeiten oder Versionserhöhungen sind davon jedoch nicht betroffen; diese werden weiterhin wie gewohnt über den Pfad aufgelöst.

Führen Go-Module während der Installation Code aus?

Go-Module verfügen über keine Skripte für den Lebenszyklus von Abhängigkeiten, die mit den Hooks von npm zur Installationszeit vergleichbar wären. Bösartiger Code in einem Go-Modul wird ausgeführt, sobald etwas ausgeführt wird, das dieses Modul importiert – sei es ein Test, ein Tool zur Erstellungszeit oder eine Produktionsbinärdatei –, in der Regel über eine init()-Funktion, die beim Start aufgerufen wird.

 

Zusammenfassung
Repojacking und warum Go-Modulpfade Übernahmeziele sind
Artikel Name
Repojacking und warum Go-Modulpfade Übernahmeziele sind
Beschreibung
Go-Modulpfade sind eher VCS-Speicherorte als eigene Namen. Was 15.000 offengelegte Repositorys zeigen und was die Prüfsummen-Datenbank leisten kann und was nicht.
Autor
Name des Herausgebers
TuxCare
Logo des Herausgebers

Schließen Sie sich 4.500+ Linux- und Open-Source-Experten an!

2x im Monat. Kein Spam.

Inhaltsübersicht
Holen Sie sich die Open-Source-Sicherheitslösungen, die Sie brauchen

Schließen Sie sich 4.500+ Linux- und Open-Source-Experten an!

2x im Monat. Kein Spam.