Skip to main content

Erweiterungen von Dependency-Confusion-Angriffen durch npm-Package-Aliasing untersuchen

Artikel von
Headshot of Nishant Jain

Nishant Jain

Snyk Advisor for malicious npm package

4. November 2021

0 Min. Lesezeit

Dependency-Confusion-Angriffe sind eine Form von Open-Source-Supply-Chain-Angriffen, bei denen Angreifer ausnutzen, wie Paketmanager Abhängigkeiten installieren. In einem früheren Beitrag haben wir untersucht, wie Sie Dependency-Confusion-Angriffe auf npm erkennen und verhindern können, um die Supply-Chain-Sicherheit zu gewährleisten.

In diesem Artikel stellen wir eine Erweiterung des Dependency-Confusion-Problems vor, die die Möglichkeiten des Package-Aliasings von npm nutzt. Dieses von der npm-Kommandozeilenanwendung bereitgestellte und dokumentierte Package-Aliasing ermöglicht es ausschließlich Nutzern, ein Paket unter einem anderen Alias zu installieren. In der eigenen Dokumentation von npm finden Sie folgendes Beispiel:

npm install my-react@npm:react

Dadurch entsteht folgender Eintrag in der package.json:

dependencies: {
  “my-react”: “npm:react”
}

Die Folgen des npm-Package-Aliasings zeigen sich darin, wie andere Tools für Pakete mit Paketmanifesten umgehen. Tatsächlich betrifft es sogar die offizielle npmjs.org-Registry selbst. Dieses Angriffsszenario hat zwar keine direkten Sicherheitsfolgen (da das aliasierte Paket immer die Version des Pakets herunterlädt, die im npm-Befehl angegeben ist), wir glauben jedoch, dass es anderen Angriffsvektoren mehr Möglichkeiten eröffnet.

Ein npm-Package-Aliasing-Angriffsszenario durchführen

Wir wollen die Auswirkungen von npm-Package-Aliasing-Angriffen nachvollziehen und zeigen, wie dies zu möglicher Dependency Confusion und zur Installation bösartiger, nicht legitimer Pakete führen kann.

Zunächst erstellen wir ein Paket namens deneuve-package-parent, das zwei verschiedene Versionen des Pakets deneuve-package-test installiert: Version 1.0.0 und 1.2.0. Version 1.0.0 wird installiert, weil sie dank des npm-Package-Aliasings unter dem Namen des erfundenen Pakets deneuve-package-private aliasiert ist.

Auf npmjs.com wird dies als eine der Abhängigkeiten von deneuve-package-parent dargestellt.

Die folgende package.json dient als vollständige Referenz für den oben beschriebenen Paketabhängigkeitsbaum:

{
  "name": "deneuve-package-parent",
  "version": "1.2.0-beta",
  "description": "This is the parent package!",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Hello\""
  },
  "author": "deneuve@wearehackerone.com",
  "license": "ISC",
  "dependencies": {
    "deneuve-package-test": "^1.2.0",
    "deneuve-package-private": "npm:deneuve-package-test@1.0.0"
  }
}

Anschließend haben wir das Paket auf npmjs veröffentlicht und die Liste der Abhängigkeiten aufgerufen.

Wie Sie sehen, führt die Liste der Abhängigkeiten in der npmjs-Registry den erfundenen Alias deneuve-package-private tatsächlich als Namen einer Abhängigkeit auf:

npm-Paketseite für deneuve-package-parent mit den Abhängigkeiten deneuve-package-test und deneuve-package-private

Der Screenshot oben zeigt eine Abhängigkeit namens deneuve-package-private, die wir in unserer package.json als Alias angelegt haben, und keine echte Abhängigkeit. Dieser Alias (der als Paketname verwendet wird) existiert in der npmjs-Registry tatsächlich nicht – es sei denn, jemand veröffentlicht ihn! Genau hier kommen die Bedenken hinsichtlich der Supply-Chain-Sicherheit ins Spiel.

Screenshot einer npm-Seite mit einem fehlenden privaten Paket und einem 404-Hinweis sowie einem Cartoon-Wombat.

Das wirft die Frage auf: Was wäre, wenn jemand solche aliasierten Pakete fände und sie dann als bösartige Pakete auf npm veröffentlichte? Verwirrte Nutzer könnten eine Abhängigkeit auf der offiziellen npmjs-Paketseite sehen und sie installieren, indem sie einfach lokal auf ihrem Entwicklungsrechner npm install ausführen:

$ npm install deneuve-package-private

Ein solches Szenario ist möglich, wenn Entwickler eine Anwendung debuggen und jede Bibliothek einzeln herunterladen. Seien wir ehrlich: Wie oft prüfen Entwickler, ob ein Paket, das sie herunterladen, tatsächlich privat sein sollte? Ein einfacher Fehler oder ein Versehen genügt. Das kann selbst dann passieren, wenn Unternehmen Richtlinien gegen das Herunterladen von Paketen ohne Scope haben.

Wir haben ein Null-Paket mit diesem Namen in der npmjs-Registry veröffentlicht. Wie Sie sehen, verweist der Tab Abhängige Pakete tatsächlich zurück auf das ursprüngliche Paket, das es als Alias unter einer seiner Abhängigkeiten referenziert:

npm-Paketseite für „dene uve-package-private“ mit einem abhängigen Paket, „dene uve-package-parent“, und Paketdetails

Das sollte ein Weckruf für alle Entwickler-Tools sein, die Paketnamen verarbeiten, etwa die npmjs-Registry selbst: Sie müssen sicherstellen, dass Nutzer nicht durch Paketnamen in die Irre geführt werden.

Dass Typosquatting mit Paketnamen nach wie vor ein wirksamer Supply-Chain-Angriffsvektor ist, zeigt, dass bereits der geringste Anschein von Legitimität (wie beim Package-Aliasing) die Erfolgschancen eines Angriffs deutlich erhöhen kann.

Hintergrund zu dieser Entdeckung

Diese Form des Supply-Chain-Angriffs wurde kürzlich von mir und dem Sicherheitsforscher Mario Stathako entdeckt und GitHub sowie npm gemeldet. Ich bin Doktorand und beschäftige mich seit einiger Zeit mit der Erforschung und Entwicklung von Ressourcen zur Bug-Bounty-Sicherheit. Außerdem bin ich Snyk Ambassador! Mario ist Penetrationstester und nimmt regelmäßig an Capture-the-Flag-Wettbewerben (CTF) und Bug-Bounty-Programmen teil.

Dependency Confusion hat mein Interesse geweckt, weil es so simpel war und gleichzeitig so große Auswirkungen hatte! Deshalb begannen Mario und ich, in den privaten Programmen von HackerOne nach diesem Problem zu suchen. Wir wollten herausfinden, wie gut Unternehmen auf verbreitete Forschungsergebnisse reagiert und diese entschärft hatten, nachdem eine gewisse Zeit vergangen war. Bei der Erstellung von POC-Paketen für die Angriffe fiel uns auf der NPM-Website ein merkwürdiges Verhalten auf: Wie die package.json-Datei für verschiedene Pakete verarbeitet wurde und wie die abhängigen Pakete und Abhängigkeiten des jeweiligen Pakets aufgelistet wurden.

Schützen Sie sich vor Risiken für die Supply-Chain-Sicherheit

Snyk hat eine Open-Source-Kommandozeilenanwendung namens snync entwickelt und veröffentlicht, die Sie dabei unterstützt, potenzielle Dependency-Confusion- und verwandte Angriffe zu erkennen und Warnungen dazu auszugeben. In diesem npm-Blogbeitrag erfahren Sie alles über das Tool: Dependency Confusion erkennen und verhindern.

Darüber hinaus hilft Ihnen der Snyk Advisor, Sicherheitsprobleme in Paketen und über ihre verschiedenen Versionen hinweg zu erkennen. Er zeigt ausdrücklich an, ob ein Paket als bösartig eingestuft wurde:

Snyk Advisor-Seite für das npm-Paket lyft-dataset-sdk, das als schädliches Dependency-Confusion-Paket gekennzeichnet ist.

Abschließend finden Sie hier einige empfohlene weiterführende Beiträge zu Best Practices für die Open-Source-Supply-Chain-Sicherheit:

Starten Sie mit Capture-the-Flag

Erfahren Sie in unserem virtuellen On-Demand-Workshop für Einsteiger, wie Sie Capture-the-Flag-Challenges lösen.