Skip to main content

Sichtbar unsichtbare schädliche Node.js-Pakete: Wenn Nischenkonfigurationen auf unsichtbare Zeichen treffen

Artikel von
Headshot of Aviad Hahami

Aviad Hahami

blog npmyarn feature

28. Februar 2022

0 Min. Lesezeit

In den vergangenen Jahren ist die Zahl der Open-Source-Pakete, die erstellt und in freier Wildbahn eingesetzt werden, massiv gestiegen. Inzwischen hat jedes Ökosystem seinen eigenen Paketmanager – und fast jeder Paketmanager birgt verborgene Möglichkeiten und Konfigurationen.

Während Entwickler fortlaufend immer mehr Pakete installieren, wächst auch das Interesse von Angreifern an den Angriffsflächen dieser Pakete. Damit beginnt die Suche nach dem perfekten, gut getarnten schädlichen Paket.

In diesem Beitrag geht es um Angriffe auf das Node.js-Ökosystem und die Paketmanager yarn und npm. Betrachten Sie ihn jedoch auch als „Aufruf zum Handeln“: Untersuchen Sie andere Ökosysteme auf ähnliche Probleme, um das Bewusstsein dafür zu schärfen und die Sicherheit unserer Community insgesamt zu verbessern.

Doch jetzt legen wir los!

Teil 1: Nischenkonfigurationen

Neulich erzählte mir ein Forscherkollege von einigen interessanten Konfigurationsoptionen in npm, die kaum bekannt sind und schwerwiegende Auswirkungen auf die Sicherheit haben können. (Später fanden wir ähnliche Optionen für yarn.) Damit kann festgelegt werden, welche Binärdatei der Paketmanager im Projektverzeichnis ausführen soll. Ja, genau: welche Binärdatei!

In der Konfiguration sind dies yarnPath in der Datei .yarnrc sowie git, shell und script-shell in der Datei .npmrc, um nur einige zu nennen. Für den vollständigen Kontext des folgenden Angriffsvektors empfehle ich Ihnen dringend, Rotems Blogbeitrag (von Cider Security) zu diesem Fund zu lesen.

Vielleicht fragen Sie sich: „Warum werden diese Dateien (die ich gerade geklont/heruntergeladen habe) überhaupt berücksichtigt?“ Die Antwort lautet: So funktionieren npm und yarn. Im Rahmen der Projektverarbeitung durchsucht der Paketmanager .rc-Dateien hierarchisch: zuerst das aktuelle Projektverzeichnis, dann das Benutzerverzeichnis und schließlich das Stammverzeichnis. Weitere Informationen dazu finden Sie in der Dokumentation zur NPM-Konfiguration.

Mit den oben genannten Optionen können wir also ein teilweise getarntes schädliches Paket erstellen (in Repositories oder Tarballs, da `.rc`-Dateien beim Ausführen von `npm install` oder einem entsprechenden Befehl nicht heruntergeladen werden). Dazu verwenden wir die folgende .yarnrc-Datei als Konfiguration:

# .yarnrc content

yarnPath: “./evil.sh”

(Hinweis: Dieses Beispiel verwendet eine .yarnrc-Datei. Eine ähnliche .npmrc-Datei mit der entsprechenden Konfigurationsoption führt jedoch zum selben Ergebnis.)

Dadurch wird bei jedem Aufruf von yarn install im Stammverzeichnis des oben genannten Projekts evil.sh ausgeführt. Jetzt müssen wir nur noch die schädliche Datei hinzufügen.

Zwei wichtige Hinweise:

  1. Auch wenn Sie --ignore-scripts oder eine entsprechende Anweisung angeben, wird das oben beschriebene Verhalten weiterhin ausgelöst.

  2. Ist ein solches Paket eine Abhängigkeit Ihres Projekts, wird die schädliche .yarnrc-Datei nicht berücksichtigt, da sie sich in node_modules befindet und keine gleichrangige Datei ist. In diesem Fall besteht also keine Gefahr.

Teil 2: Code vor aller Augen verbergen

Ein weiteres heißes Thema des vergangenen Jahres war Trojan Source Code – also schädlicher Code, der durch Zeichen mit anderen Unicode-Werten entsteht, als es ihrem üblichen Erscheinungsbild entspricht.

Das Prinzip ist recht einfach: Einige Zeichen (keine Leerzeichen, CR, LF usw.) werden beispielsweise als Leerraum dargestellt, sind aber dennoch gültige Zeichenfolgen.

Ein etwas genauerer Blick: Das scheinbar leere Zeichen „…“ (hexadezimal 0x3164) heißt „HANGUL FILLER“. Wie Sie (nicht) sehen können, ist es kein Leerzeichen, sondern ein gültiger „Buchstabe“. Damit können wir bestimmte Logik in Codeausschnitten verbergen und bei der Einführung schädlichen Codes unentdeckt bleiben.

Für unsere Demonstration reichen die obigen Informationen aus, deshalb gehe ich nicht weiter auf das Thema ein. Wenn Sie mehr Informationen, Kontext und Beispiele wünschen, empfehle ich Ihnen dringend, Folgendes zu lesen:

Teil 3: Verborgene Binärdateien + verborgene Konfigurationen = RCE

Nachdem wir die Grundlagen geklärt haben, sind die nächsten Schritte unseres Angriffs einfach:

  1. Erstellen Sie ein scheinbar harmloses Paket.

  2. Erstellen Sie eine schädliche Datei mit einem verborgenen Zeichen im Namen.

  3. Erstellen Sie eine .rc-Datei.

  4. Legen Sie den Konfigurationsparameter so fest, dass er auf den Binärdateinamen mit dem unsichtbaren Zeichen verweist.

Nach diesen Schritten sind wir bereit. Betrachten wir den Angriff nun aus Sicht der Opfer:

Wenn ein Entwickler auf ein solches Paket stößt, ohne den Angriffsvektor zu kennen, wird er die Warnsignale wahrscheinlich übersehen.

Vielleicht ist er etwas vorsichtig und führt ls -l aus. Dann sieht er Folgendes:

$ ls -l
total 24
-rw-r--r--  1 root  staff   27 Nov 16 13:48 index.js
-rw-r--r--  1 root  staff  295 Nov 16 17:47 package.json
-rw-r--r--  1 root  staff  354 Nov 16 17:47 yarn.lock

Da die Ausgabe nicht ungewöhnlich wirkt, ist dies die erste Falle. Die meisten Betroffenen führen an diesem Punkt yarn install aus und werden zum Opfer.

Nehmen wir jedoch an, unser Ziel ist ein erfahrener Entwickler, der in ls. das Flag „unsichtbare Zeichen anzeigen“ ergänzt. Das ergibt:

$ ls -la
total 32
drwxr-xr-x  7 root  staff  224 Feb 14 16:18 .
drwxr-xr-x  6 root  staff  192 Nov 25 17:48 ..
-rw-r--r--  1 root  staff  109 Nov 16 15:27 .yarnrc
-rw-r--r--  1 root  staff   27 Nov 16 13:48 index.js
-rw-r--r--  1 root  staff  295 Nov 16 17:47 package.json
-rw-r--r--  1 root  staff  354 Nov 16 17:47 yarn.lock
-rwxr-xr-x  1 root  staff  197 Feb 14 16:28

Nun fragt sich das Ziel vielleicht: „Okay, was steht in der .rc-Datei?“ (und ignoriert dabei völlig die unauffällige, unsichtbare Datei) und zeigt sie mit cat an. Das Ergebnis:

$ cat .yarnrc

yarn-path "./"

Das ist die zweite Falle.

Den meisten Entwicklern ist nicht bewusst, dass yarn (oder npm) benutzerdefinierte Binärdateien aufrufen kann. Etwas wie die obige Ausgabe wirkt zwar merkwürdig, aber dort steht doch nicht „evil.sh“, oder?

Die dritte Falle ist ganz einfach: Das Ziel sieht die Datei schlicht nicht. Selbst wenn es die .rc-Datei entdeckt und sich die yarn-path-Spezifikation ansieht (dasselbe gibt es auch bei npm), könnte es annehmen, dass die Eigenschaft ins Leere verweist, und anschließend doch den Paketmanager aufrufen.

In meinem PoC führt yarn install zu folgendem Ergebnis:

$ yarn install
Okayyyy lesgo!

Schutzmaßnahmen und Überlegungen

So können Sie sich schützen:

  1. Vertrauen Sie niemals Code aus Drittquellen. Vergewissern Sie sich stets, was Sie geklont oder heruntergeladen haben, und achten Sie auf ungewöhnliches Verhalten und merkwürdige Konfigurationen.

  2. Führen Sie Code in einer Sandbox aus. Führen Sie Code aus Drittquellen stets in einer Sandbox oder containerisierten Umgebung aus. So wirkt sich ein schädliches Paket wahrscheinlich nicht auf Ihr System aus und kann Ihren Rechner nicht kompromittieren.

    Hinweis: Auch die Ausführung in einer Sandbox ist möglicherweise nicht hundertprozentig sicher, da es Kernel-Schwachstellen, Sandbox-Ausbrüche usw. gibt. In einer solchen Umgebung reduzieren Sie das Risiko jedoch erheblich und blockieren die meisten einfachen Angriffe (etwa einfache Reverse-Shells oder Ähnliches).

Und damit haben wir den Angriff abgewehrt.

Das Faszinierende an diesem Angriffsvektor ist, dass er vollständig sichtbar und doch unsichtbar ist.

Vielleicht sagen Sie: „Ich führe immer ls -la aus, überprüfe alle Dateien und kenne sämtliche Konfigurationsoptionen des Paketmanagers genau.“ Gut, aber stimmt das wirklich? Und gilt das auch für alle in Ihrer Organisation?

Und wie bei Bloom-Filtern lautet die Antwort hier: „Nein heißt nein, Ja heißt vielleicht.“

Zum Schluss möchte ich nochmals betonen: Dieser Beitrag ist ein Aufruf zum Handeln – nicht zur Ausnutzung von Schwachstellen. Die Community sollte das Bewusstsein für solche Angriffsvektoren schärfen. Da alle Anwendungen entwickeln und nahezu blind Abhängigkeiten installieren, ist es entscheidend, andere auf verdächtige Konfigurationen hinzuweisen.

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.

Weiterlesen

illustration hero ai
Blog

PHP behebt zwei kritische unauthentifizierte RCE-Schwachstellen (CVE-2026-109618, CVE-2026-109619): Jetzt aktualisieren

Zwei kritische Sicherheitslücken im Request-Lebenszyklus von PHP können unauthentifizierte Remote Code Execution ermöglichen. Aktualisieren Sie auf eine korrigierte Version oder installieren Sie für ältere Versionen einen Backport des Anbieters.

blog feature ai lilac
Blog

Mit agentischer Behebung Ihren Schwachstellen-Backlog in Pull Requests verwandeln

Der Evo Remediation Agent ist jetzt in der öffentlichen Vorschau verfügbar und erweitert Evo Agentic AppSec um die automatisierte Auflösung von Abhängigkeiten. AppSec-Teams können jetzt kontinuierliche Behebungskampagnen durchführen

AI Background min crop
Blog

KI ruft alle Risiken auf den Plan, die Sie akzeptiert haben: Sieben Erkenntnisse aus dem AI Security Panel: Unfiltered

KI macht Angriffe günstiger und schneller und legt Risiken offen, die Unternehmen bereits tragen. Vier Sicherheitsverantwortliche erklären, warum Abwehr in Maschinengeschwindigkeit und schnellere Behebung jetzt unverzichtbar sind.