Dateisystem-Übernahme durch Schwachstellen im npm-JavaScript-Paketmanager verstehen
7. Januar 2020
0 Min. LesezeitAm 11. Dezember 2019 wurde eine Sicherheitslücke öffentlich bekannt gemacht, die alle wichtigen JavaScript-Paketmanager (npm, yarn und pnpm) betrifft. Die vom Sicherheitsforscher Daniel Ruf entdeckte Schwachstelle ermöglicht es Angreifern, mit verschiedenen Methoden beliebige Dateien zu überschreiben.
In diesem Artikel:
Wie wirkt sich diese Sicherheitslücke auf den npm-Paketmanager-Client aus?
Wie lässt sich diese npm-Sicherheitslücke in der Praxis ausnutzen?
Wie funktionieren Node.js-Kommandozeilenpakete?
npm-Pakete enthalten häufig einen bin-Schlüssel in der Paketmanifestdatei – package.json. Der Paketmanager-Client – zum Beispiel npm oder eine Alternative – verwendet diesen bin-Schlüssel, um ausführbare Dateien zu deklarieren, die über die globale Umgebungsvariable $PATH in Ihrer Eingabeaufforderung verfügbar sind.
Wahrscheinlich ist Ihnen diese Funktion schon begegnet, wenn Sie Kommandozeilenpakete global installiert haben – etwa Angular CLI über @angular/cli, typescript oder die Snyk CLI über snyk —. Diese sind dann unabhängig von einem bestimmten npm-Projektverzeichnis überall in Ihrem Pfad verfügbar. Um zu verstehen, wie der bin-Schlüssel verwendet wird, sehen wir uns mit unpkg an, wie das Angular-CLI-Projekt funktioniert. Dazu rufen wir die package.json auf der unpkg-Website auf.

Wie oben zu sehen ist, deklariert die Manifestdatei package.json in dieser Paketversion eine ausführbare Datei namens ng, die auf eine im Paket enthaltene Datei unter ./bin/ng verweist.
Diese JavaScript-Datei ./bin/ng wird für den Benutzer ausführbar gemacht, indem am Anfang der Datei eine Unix-Shebang-Anweisung angefügt wird. Diese Anweisung teilt der Shell mit, welcher Interpreter zum Ausführen der Datei verwendet werden soll. Bei Node.js-Anwendungen ist die Node.js-Binärdatei auf dem Betriebssystem des Benutzers installiert.
Im Fall von Angular CLI ist der Inhalt der ausführbaren Datei in der folgenden Abbildung zu sehen:

Wie wirkt sich diese Sicherheitslücke auf den npm-Paketmanager-Client aus?
Um die Auswirkungen dieser Schwachstelle zu verstehen, müssen wir uns npm etwas genauer ansehen – insbesondere die Mechanismen, mit denen npm dafür sorgt, dass installierte ausführbare Dateien für Benutzer verfügbar sind.
Der npm-Client verwaltet deklarierte ausführbare Dateien („Bins“) global installierter Pakete in einem bestimmten Verzeichnis. Dort legt er symbolische Links von den ausführbaren Dateien dieser Pakete zu Links im genannten Verzeichnis an.
Um herauszufinden, welches Verzeichnis für diese ausführbaren Dateien verwendet wird, gehen Sie mit dem npm-Client wie folgt vor:
Wenn Sie die in Ihrer Shell verfügbare Umgebungsvariable $PATH prüfen, finden Sie einen Eintrag, der dem Verzeichnis für Ihr Betriebssystem entspricht. So können Sie von jedem Verzeichnis im Betriebssystem aus auf global installierte Pakete mit deklarierten ausführbaren Dateien zugreifen.
Mit diesen Informationen stellt sich unweigerlich die Frage, ob ein Paket eine ausführbare Datei deklarieren kann, die von einem anderen Paket bereitgestellt wird. Genau das wollte Daniel herausfinden. Dabei entdeckte er Schwachstellen, durch die sich beliebige Dateien in den wichtigen Paketmanagern npm, yarn und pnpm überschreiben lassen.
Wie lässt sich diese npm-Sicherheitslücke in der Praxis ausnutzen?
Bei Snyk reproduzieren wir diese Schwachstelle zum Schreiben beliebiger Dateien und zeigen, wie sie ausgenutzt werden kann. Dabei nutzen wir die Proof-of-Concepts von Daniel, die er dem Snyk-Sicherheitsteam zur Verfügung gestellt hat.
Das erste Paket definiert global ausführbare Dateien wie folgt:
Dabei gibt die ausführbare Datei curl-test einfach Text in der Konsole aus:
Wenn wir dieses Paket global mit npm install -g binary-replace installieren und anschließend den Befehl curl-test in der Shell ausführen, sollte hi auf dem Bildschirm erscheinen.
Stellen Sie sich nun ein weiteres Paket vor: binary-replacer-2. Auch dieses definiert eine ausführbare Datei und verwendet denselben bin-Schlüssel wie das vorherige Paket: curl-test
Sobald der Benutzer dieses Paket global installiert, überschreibt npm den vorherigen symbolischen Link mit der vom neuen Paket bereitgestellten ausführbaren Datei. In diesem Beispiel ist diese harmlos:
Was aber, wenn ein schädliches Paket auf einige der bekannteren global verwendeten Pakete abzielt? Die Möglichkeiten sind vielfältig – vom Paket now von Zeit bis zur CLI fkill von Sindre Sorhus.
Außerdem hat Daniel zahlreiche Varianten dieser Schwachstelle in npm, yarn und pnpm aufgezeigt. Was wäre zum Beispiel, wenn der Schlüssel statt curl-test einen relativen Linkpfad enthielte?
Oder wenn der Schlüssel auf einen absoluten Pfad zu einem bekannten Kommandozeilentool gesetzt würde, das häufig von Benutzern in einer Shell-Eingabeaufforderung verwendet wird, etwa:
Es ist bemerkenswert, dass pnpm unter der Leitung des alleinigen Entwicklers Zoltan Kochan in den meisten Fällen das Richtige tut und nur dann anfällig ist, wenn ein relativer Pfad angegeben wird. Das ist trotzdem ein Problem. Ein Upgrade auf korrigierte npm-Versionen ist ebenfalls möglich.
Warum ist diese npm-Sicherheitslücke so schwerwiegend?
Die Schwachstelle ist besonders gravierend, weil beliebige Dateien auch dann überschrieben werden können, wenn Pakete mit dem npm-Kommandozeilenflag —ignore-scripts installiert werden. Man könnte erwarten, dass dadurch verhindert wird, dass schädliche Binärdateien auf diese Weise vorgehen.
Darüber hinaus ist dieser Angriff nicht nur bei global installierten Paketen und ihren ausführbaren Dateien relevant, sondern ebenso bei transitiven Abhängigkeiten in Ihrem Projekt. Werden Abhängigkeiten mit einem gewöhnlichen npm install installiert, kann ein Paket beliebige Dateien innerhalb und außerhalb des Projektverzeichnisses überschreiben. Dies kann unter anderem zum Einschleusen von Malware, zu einem Angriff durch Manipulation von Lockfiles oder auf andere Weise zur Manipulation des Dateisystems führen.
Bin ich betroffen, und was sollte ich tun?
In zwei Fällen besteht für Sie das Risiko, betroffen zu sein:
Sie installieren ein schädliches Paket – entweder, weil Sie durch Social Engineering dazu verleitet wurden, oder weil ein Angreifer beliebte Pakete durch Typosquatting imitiert und Sie eines davon installieren.
Ein nicht schädliches Paket wird kompromittiert und seine package.json-bin-Schlüssel werden so geändert, dass sie Dateien überschreiben und zugleich eine schädliche Datei zur Ausführung einschließen. Das ist zwar sehr unwahrscheinlich, ist aber bereits zweimal vorgekommen: [1], [2]
Die Auswirkungen dieser Schwachstelle führten auch zu Sicherheitsupdates für Node.js, da der npm-Paketmanager-Client mit Node.js ausgeliefert wird und ein Update auf die korrigierte npm-Version 6.13.4 erforderlich war.
Daniel meldete die Erkenntnisse zur Sicherheitslücke zunächst dem Snyk-Sicherheitsforschungsteam, um die koordinierte, verantwortungsvolle öffentliche Offenlegung bei allen Projekten und Maintainerinnen und Maintainer der betreffenden Paketmanager zu unterstützen. Weitere Informationen zu den Angriffsarten veröffentlichte er in seinem Blog.
Wenn Sie eine der folgenden Versionen von npm, yarn oder pnpm verwenden, sind Sie gefährdet und sollten unbedingt sofort ein Upgrade durchführen:
npm < v6.13.4: CVE-2019-16776 und CVE-2019-16777
pnpm < v4.5.0: CVE-2019-10773
yarn < v1.21.1: CVE-2019-10773
Es kommt zwar nicht häufig vor, dass npm, yarn oder pnpm als Projektabhängigkeit eingebunden werden. Wenn Snyk Ihr Projekt jedoch überwacht und anfällige Versionen dieser Paketmanager findet, werden Sie durch die regulären Snyk-Warnmeldungen benachrichtigt. Wenn Sie außerdem Ihr GitHub-Repository verbunden haben (oder Bitbucket), erstellen wir automatisch einen Pull Request, damit Sie ein Upgrade auf korrigierte Versionen dieser Paketmanager durchführen können.
Wir empfehlen Ihnen außerdem, beim Umgang mit Paketmanagern wie npm sichere Entwicklungspraktiken anzuwenden. Damit es Ihnen leichter fällt, haben wir Sicherheitsrichtlinien und Best Practices zusammengestellt, die Sie unter 10 npm-Sicherheits-Best-Practices finden.
Glauben Sie, eine Schwachstelle in einem Open-Source-Paket entdeckt zu haben? Wir bei Snyk schätzen die Security-Community und sind überzeugt, dass eine verantwortungsvolle Offenlegung von Sicherheitslücken in Open-Source-Paketen dazu beiträgt, die Sicherheit und Privatsphäre der Nutzer zu gewährleisten. Wenn Sie glauben, eine Schwachstelle in einem Open-Source-Paket entdeckt zu haben, können Sie sie über das Snyk Open Source Package Vulnerability Disclosure program melden. Wir kümmern uns dann um den Rest! https://snyk.io/vulnerability-disclosure/
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.



