123% mehr gemeldete CVEs pro Tag in 2026 als im Vorjahr.

Lieferkette

Was ist Dependency Confusion?

Dependency Confusion ist ein Angriff, bei dem ein Build das öffentliche Paket eines Angreifers statt Ihres gleichnamigen privaten Pakets installiert. Niemand vertippt sich. Der Angreifer muss nur einen internen Paketnamen in Erfahrung bringen und ihn mit einer hohen Versionsnummer in einer öffentlichen Registry veröffentlichen, den Rest erledigt ein falsch konfigurierter Build.

Aktualisiert am

So funktioniert ein Dependency-Confusion-Angriff

  1. Einen internen Namen finden. Private Paketnamen sickern über öffentlichen Code, JavaScript-Bundles, Fehlermeldungen und in Repositories zurückgelassene Manifeste durch.
  2. Denselben Namen öffentlich publizieren. Der Angreifer registriert ihn auf npm, PyPI oder einer anderen öffentlichen Registry, mit einer sehr hohen Versionsnummer.
  3. Auf einen Build warten. Ein Paketmanager, der so eingerichtet ist, dass er sowohl die interne als auch die öffentliche Registry prüft, findet zwei Kandidaten und bevorzugt die höhere Version.
  4. Im Unternehmen ausführen. Das Install-Skript des Pakets läuft auf einem Entwicklerrechner oder einem CI-Runner, mit Zugriff auf alles, was dort liegt.

Die Forschung, die dem Angriff den Namen gab

Im Februar 2021 veröffentlichte der Sicherheitsforscher Alex Birsan die Technik. Damit hatte er Code in mehr als 35 Organisationen zur Ausführung gebracht, darunter Apple, Microsoft und PayPal, im Rahmen von Bug-Bounty-Programmen oder mit Erlaubnis. Sie funktionierte in allen drei Sprachen, die er testete, und innerhalb weniger Tage nach der Veröffentlichung begannen Angreifer, sie zu kopieren.

Warum es passiert

Die Ursache ist ein Paketmanager, der mehrere Registries als gleichwertig behandelt. Das klassische Beispiel ist Python: pips --extra-index-url fügt neben PyPI eine zweite Quelle hinzu, und pip installiert möglicherweise das öffentliche Paket, wenn es eines mit demselben Namen findet.

# Unsafe for private packages: both indexes are candidates
pip install --extra-index-url https://pypi.internal.example/simple my-internal-lib

# Safer: one index you control, which proxies public packages
pip install --index-url https://pypi.internal.example/simple my-internal-lib

npm hat dasselbe Problem bei internen Namen ohne Scope, während ein an Ihre Registry gebundener Scope es vermeidet.

# .npmrc: everything under @acme comes only from your registry
@acme:registry=https://npm.internal.example/

So verhindern Sie Dependency Confusion

  • Nutzen Sie eine einzige Quelle der Wahrheit. Richten Sie Builds auf eine einzige interne Registry aus, die öffentliche Pakete proxyt, und konfigurieren Sie sie so, dass interne Namen nie öffentlich aufgelöst werden.
  • Nutzen Sie Scopes oder Namespaces. Sichern Sie sich einen Scope wie @acme in der öffentlichen Registry, und ordnen Sie ihn Ihrer privaten zu.
  • Reservieren Sie Ihre Namen. Registrieren Sie interne Paketnamen in öffentlichen Registries, damit es niemand anders tun kann.
  • Fixieren und verifizieren. Committen Sie ein Lockfile und nutzen Sie Hash-Prüfungen, etwa pips --require-hashes, damit ein anderes Paket die Installation fehlschlagen lässt. Siehe was ein Lockfile leistet und was nicht.
  • Begrenzen Sie, wohin sich Builds verbinden können. Wenn ein Build nur Ihre Registry erreichen kann, kann er das Paket des Angreifers gar nicht laden. Siehe GitHub-Actions-Egress-Richtlinie.
  • Prüfen Sie, was nach außen dringt. Durchsuchen Sie öffentlichen Code und Client-Bundles nach Ihren internen Paketnamen.

Dependency Confusion vs. Typosquatting

Typosquatting setzt darauf, dass sich jemand beim Namen eines öffentlichen Pakets vertippt. Dependency Confusion nutzt den exakten Namen eines privaten Pakets und setzt darauf, wie der Build konfiguriert ist. Beide führen zum selben Ergebnis: Code des Angreifers läuft in Ihrem Build. Wie sie mit anderen Angriffen zusammenhängen, lesen Sie unter Was ist ein Lieferkettenangriff.

So erkennen Sie, ob Sie betroffen waren

Suchen Sie nach internen Paketnamen, die aus einer öffentlichen Registry aufgelöst wurden, oder nach Versionen, die es in Ihrer internen Registry nicht gibt. Allein aus einem Lockfile ist das schwer zu erkennen, denn die Frage ist, woher ein Paket während des Builds tatsächlich kam.

Wie CRACI hilft

CRACI arbeitet an dem Punkt, an dem das Paket geladen wird. Als Ihr GitHub-Actions-Runner setzt es eine Egress-Richtlinie mit typisierten Quellen für Registries durch, sodass sich ein Build auf die von Ihnen erlaubten Registries beschränken lässt. Außerdem zeichnet es jedes Paket, das jeder Job geladen hat, in einer SBOM auf, sodass Sie sehen, was in einen Build gelangt ist. CRACI erkennt nicht, dass ein Paket bösartig ist. Behalten Sie Ihre Registry-Konfiguration also als erste Verteidigungslinie. Siehe Best Practices für Software-Lieferkettensicherheit.

Dependency Confusion: häufig gestellte Fragen

Was ist ein Dependency-Confusion-Angriff?

Ein Angriff, bei dem ein öffentliches Paket mit demselben Namen wie ein privates versehentlich installiert wird, weil der Paketmanager beide Registries prüft und die höhere Version bevorzugt.

Wie unterscheidet sich Dependency Confusion von Typosquatting?

Typosquatting setzt darauf, dass sich jemand beim Namen eines öffentlichen Pakets vertippt. Dependency Confusion nutzt den exakten Namen eines privaten Pakets und setzt auf eine Build-Konfiguration, die öffentliche Registries prüft.

Wie verhindern Sie Dependency Confusion?

Mit einer einzigen internen Registry, Paketnamen mit Scope, Lockfiles mit Hash-Prüfung und Regeln, die begrenzen, welche Registries Ihre Builds erreichen können. Auch das öffentliche Reservieren Ihrer internen Namen hilft.

Ist --extra-index-url sicher?

Nicht für private Pakete. Damit sind beide Indizes Kandidaten, sodass ein öffentliches Paket mit demselben Namen installiert werden kann. Nutzen Sie --index-url mit einem einzigen Index, den Sie kontrollieren.

Wer hat Dependency Confusion entdeckt?

Der Sicherheitsforscher Alex Birsan veröffentlichte die Technik im Februar 2021, nachdem er sie im Rahmen von Bug-Bounty-Programmen oder mit Erlaubnis gegen mehr als 35 Organisationen eingesetzt hatte.

Begrenzen Sie, woher Ihre Builds laden können

Erlauben Sie nur die Registries, die ein GitHub-Actions-Job braucht, und sehen Sie jedes Paket, das er geladen hat.

Demo buchen