Skip to main content

Die Prototype-Pollution-Sicherheitslücke in minimist im Detail

Artikel von
Headshot of Kirill Efimov

Kirill Efimov

26. März 2020

0 Min. Lesezeit

Am 11. März 2020 veröffentlichte Snyk eine Prototype-Pollution-Sicherheitslücke mittleren Schweregrads (CVE-2020-7598), die das minimist-npm-Paket betrifft. Sie ist Teil der laufenden Forschungsarbeit des Snyk-Security-Research-Teams, das zuvor ähnliche Sicherheitslücken in anderen bekannten JavaScript-Bibliotheken wie lodash und jQuery aufgedeckt hatte.

Was ist eine Prototype-Pollution-Schwachstelle?

Diese Sicherheitslücke, die sich als Prototype Pollution äußert, ermöglicht es Angreifern, den Prototyp eines JavaScript-Anwendungsobjekts zu überschreiben. Dadurch können vom Angreifer kontrollierte Eigenschaften in Objekte eingeschleust werden. Dies kann entweder zu einem Denial-of-Service führen, indem JavaScript-Ausnahmen ausgelöst werden, oder den Anwendungscode manipulieren, sodass der Angreifer den eingeschleusten Codepfad erzwingt.

Die aktuelle Forschung des Snyk-Teams deckte auch ähnliche Sicherheitslücken in anderen npm-Paketen auf, von denen einige ebenso bekannt sind wie yargs-parser:

Suchergebnisse der Snyk Vulnerability DB für „minimist“ mit npm-Command-Injection- und Prototype-Pollution-Schwachstellen.
von Snyks Security-Researchteam entdeckte Prototype-Pollution-Schwachstellen: https://snyk.io/vuln?type=npm

Das Snyk-Security-Research-Team hält sich an die Richtlinien für verantwortungsvolle Offenlegung und hat mit den Maintainerinnen und Maintainern von minimist, yargs-parser und anderen zusammengearbeitet, um unsere Erkenntnisse mitzuteilen, zu validieren und gemeinsam mit den jeweiligen Maintainerinnen und Maintainern zu überprüfen. Diese bestätigten die verwundbare Angriffsfläche und stimmten unseren Erkenntnissen zu.

Wir möchten uns bei den Maintainerinnen und Maintainern bedanken, die schnell reagiert und zeitnah Fixes veröffentlicht sowie Sicherheitsfixes auf ältere Versionen zurückportiert haben – beispielsweise den Sicherheitsfix für minimist für Versionen vor 1.0.0 und den Sicherheitsfix für yargs-parser für Versionen vor 13.1.2.

Prototype Pollution in CLI-Parsern

Bitte beachten Sie, dass ich in diesem Beitrag nicht auf die Grundlagen der Prototype Pollution eingehe – dazu gibt es bereits genügend Artikel. Auch wir haben in unserem Blog einen ausführlichen Beitrag mit einer guten Einführung in die Grundlagen von Prototype-Pollution-Sicherheitslücken veröffentlicht.

Stattdessen möchte ich in diesem Blogbeitrag Folgendes behandeln:

  1. Die Funktionsweise von Parsern für Befehlszeilenargumente (CLI) und ihre heutige gängige Verwendung im JavaScript-Ökosystem erläutern.

  2. Anhand konkreter Beispiele verwundbarer Pakete zeigen, wie Anwendungen, die solche Parser verwenden, durch Prototype-Pollution-Angriffsvektoren gefährdet sein können.

  3. Die Gründe für die Einstufung des Schweregrads und die allgemeine Bewertung der Auswirkungen dieser Sicherheitslücken erläutern.

Es ist eine Bibliothek zum Parsen von Befehlszeilenargumenten – greift man damit nicht im Grunde sich selbst an?

Sowohl minimist als auch yargs-parser sind JavaScript-Bibliotheken, die Argumente für Node.js-Befehlszeilenanwendungen parsen. Sehen wir uns an, wie eine Node.js-CLI durch unzureichende Eingabevalidierung (CWE-20) zu einer lokalen Rechteausweitung führen kann – eine häufige Sicherheitslücke mit Tausenden dokumentierten Fällen und CVEs. 

Im folgenden Beispiel erstellen wir ein Systemprogramm, mit dem Benutzerinnen und Benutzer ohne Root-Rechte einen Server neu starten können. In diesem Beispiel verwenden wir minimist nur zu einem Zweck: um eine kurze Hilfe für die Befehlszeilenoption --help anzuzeigen.

Der folgende Code zeigt unsere kleine Node.js-CLI namens u-reboot:

const argv = require('minimist')(process.argv.slice(2));
const cp = require('child_process');
if (argv.help) {
    console.log("My awesome reboot utility with no root access required");
} else {
    cp.execSync('reboot', {uid: 0});
}

Damit sich dieses hervorragende Tool bequemer verteilen lässt, müssen wir es als eigenständige Binärdatei erstellen. Dazu können wir pkg verwenden:

npm install -g pkg
pkg u-reboot.js --target node10-linux-x64

Damit es funktioniert, müssen wir der Binärdatei schließlich die passenden Berechtigungen erteilen:

chown root u-reboot
chmod 4555 u-reboot

4555 steht für Lese- und Ausführungsrechte für alle Benutzerinnen und Benutzer sowie das setuid-Flag. Mehr über setuid erfahren Sie hier. Kurz gesagt ermöglicht es, die Binärdatei mit den Berechtigungen ihres Eigentümers auszuführen (in unserem Fall des Root-Benutzers).

Wir haben jetzt ein Befehlszeilentool namens u-reboot, das alle Benutzerinnen und Benutzer aufrufen können, um den Server oder die Workstation neu zu starten. Sie sollen damit jedoch nichts anderes auf dem Server tun können.

Wie kann eine solche Befehlszeilenanwendung nun missbraucht werden? Denken Sie daran: Die Benutzerinnen und Benutzer haben nur geringe Berechtigungen auf dem Server und sollten keine anderen Befehle als Root ausführen können.

Node.js-CLI-Anwendungen ausnutzen

Die Sicherheitslücke in minimist ermöglicht es uns, den Prototyp von Object zu manipulieren. Dadurch wird u-reboot plötzlich anfällig für eine klassische Rechteausweitung.

printf '#!/bin/shn id' > /tmp/exploit
chmod +x /tmp/exploit
u-reboot --__proto__.shell /tmp/exploit

Sehen Sie uid=0(root) in der Ausgabe? Jetzt können wir durch Ausnutzen der Prototype-Pollution-Sicherheitslücke in minimist, das die u-reboot-CLI verwendet, beliebige Befehle mit Root-Berechtigungen ausführen.

Der Angriff ist möglich, weil child_peorccess.execSync ein options-Objekt mit einer optionalen shell-Eigenschaft hat. Ist shell leer, verwendet execSync laut Dokumentation /bin/sh. Wenn wir jedoch bei allen Objekten die Eigenschaft shell auf /tmp/exploit setzen, verwendet execSync unseren Exploit als Shell.

Das scheint eine lokale Sicherheitslücke zu sein. Warum sprechen Sie von einem netzwerkbasierten Angriffsvektor?

Das erinnert mich an die 2014 veröffentlichte Sicherheitslücke Shellshock. Bei Shellshock lässt sich die Bash-Shell dazu bringen, beliebigen Code auszuführen, der über Umgebungsvariablen eingeschleust wurde. Die Sicherheitslücke klingt völlig lokal – wer sonst kann Umgebungsvariablen kontrollieren? Doch die Bash-Shell wird sehr häufig verwendet: Viele Webdienste nutzen sie zur Verarbeitung von Anfragen und ermöglichen Angreifern so, beliebige Befehle auszuführen. Wenn Sie mit dieser Sicherheitslücke noch nicht vertraut sind, empfehle ich Ihnen diese kurze Erklärung.

Geht es bei dieser Sicherheitslücke nur um eine Rechteausweitung? Nein. Unser Forschungsteam untersuchte verschiedene Anwendungsfälle von minimist und yargs-parser und fand einige interessante Beispiele. Ich werde nicht jeden Fall ausführlich behandeln – die Beispiele sollen zeigen, dass CLI-Argumentparser nicht immer so eingesetzt werden, wie man es erwarten würde.

  1. Terminal in React – eine React-Komponente, die ein Terminal in einem Webbrowser emuliert. Sie verwendet minimist, um CLI-Argumente von Befehlen zu parsen. Weitere Beispiele für Terminalemulatoren finden Sie hier.

  2. Chatbot-Argumente sehen oft wie CLI-Argumente aus, oder? Wir haben viele Beispiele gefunden, bei denen CLI-Argumentparser tatsächlich für diesen Zweck eingesetzt werden: 1, 2, 3, 4, 5.

  3. apibone – eine Bibliothek, die Schnittstellen für abfragbare Dienste bereitstellt. Sie abstrahiert einfach Anforderungs- und Antwortobjekte für die definierten Funktionen. Zum Parsen von Teilen von HTTP-Abfragen verwendet sie yargs-parser.

Weitere Beispiele finden Sie, wenn Sie in Open-Source-GitHub-Repositories genau nach unterschiedlichen, nicht offensichtlichen Verwendungsmustern suchen.

Sollten diese Anwendungen auf eine Bibliothek wie minimist verzichten, die zum Parsen von CLI-Argumenten gedacht ist, und sie stattdessen für Web- und Netzwerkanwendungen einsetzen? Vielleicht. Bei Snyk sind wir jedoch der Meinung, dass Parser besonders sicherheitskritische Codekomponenten sind. Sie befinden sich meist am Anfang eines Datenverarbeitungsprozesses und interagieren direkt mit Benutzereingaben.

Außerdem ist minimist eine allgemeine Bibliothek zum Parsen von Argumenten: Sie ist nicht direkt an etwas wie Node.js’ process.argv gebunden. Stattdessen können Sie minimist ein Array aus Zeichenfolgen übergeben, das dann so geparst wird, als wären die Daten als CLI-Argumente gedacht.

Überlegen Sie einmal: Wie viele Probleme haben XML-Parser verursacht? Oder der Deserialisierungsmechanismus von Java? Ein gutes Beispiel, an das Sie sich wahrscheinlich erinnern, ist der bourne-JSON-Parser, den Eran Hammer schrieb, nachdem er sich mit Prototype-Pollution-Problemen in hapi und joi befasst hatte. Der Bourne-JSON-Parser wurde für genau einen Zweck entwickelt: um vor __proto__-Eigenschaften in einer JSON-Nutzlast zu schützen. Mehr darüber erfahren Sie in seinem Artikel.

Wie stufen wir den Schweregrad dieser Sicherheitslücke ein?

Zur Beschreibung der Sicherheitslücke haben wir den folgenden CVSS-Vektor zugewiesen: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L.

  1. Angriffsvektor – Netzwerk. Wir haben die Verwendung von minimist und yargs-parser in mehreren Chatbots und Webanwendungen gefunden. Auch wenn es keine bewährte Praxis ist, diese Bibliotheken in solchen Fällen einzusetzen, können wir nicht ignorieren, dass sie tatsächlich verwendet werden.

  2. Angriffskomplexität – Hoch. Prototype-Pollution-Sicherheitslücken werden erst dann zu einer realen Bedrohung, wenn Angreifer ein geeignetes Gadget finden, um eine Remotecodeausführung oder eine andere für den weiteren Angriff erforderliche Aktion auszuführen. In unserem Beispiel übernimmt der Aufruf „execSync“ die Rolle eines solchen Gadgets.

  3. Erforderliche Berechtigungen – Keine. Ein Angreifer muss eine Zeichenfolge senden können, die als CLI-Argumente behandelt wird. Besondere Berechtigungen sind nicht erforderlich.

  4. Interaktion mit Benutzerinnen und Benutzern – Keine.

  5. Umfang – Unverändert. Diese beiden Eigenschaften bedürfen meiner Ansicht nach keiner weiteren Erläuterung.

  6. Vertraulichkeit – Niedrig.

  7. Integrität – Niedrig.

  8. Verfügbarkeit – Niedrig. Alle drei Eigenschaften werden aus den in Punkt 2 beschriebenen Gründen als niedrig eingestuft: Prototype-Pollution-Sicherheitslücken sollten im Kontext einer Anwendung betrachtet werden.

Diese Sicherheitslücke hat definitiv keinen hohen Schweregrad (CVSS-Score: 5,6 – mittel). Unser Forschungsteam sieht jedoch eindeutig zahlreiche verschiedene Angriffsszenarien. Wir sind außerdem der Meinung, dass die Popularität der beiden hier genannten Bibliotheken eine verantwortungsvolle Offenlegung und Behebung erforderlich macht.

Was sollte ich als Nächstes tun?

  • Wenn Sie Snyk bereits zur Überwachung Ihrer Anwendungen verwenden und Ihre GitHub- oder Bitbucket-Repositories verbunden haben, sollten Sie bereits einen automatisierten Pull Request von Snyk erhalten haben. Dieser schlägt ein Upgrade Ihrer Projekte auf Versionen der verwundbaren Bibliotheken vor, in denen die Sicherheitslücke behoben ist.

  • Wenn Sie Snyk nicht verwenden, können Sie Ihre Projekte hinzufügen. Snyk ist für Open Source kostenlos. Importieren Sie Ihre Projekte dazu aus Ihren Code-Repositories in das Snyk-Dashboard.

Starten Sie mit Capture the Flag

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

Weiterlesen

Blog

Frontier-Modelle fanden die Schwachstellen. Nur der Angreifer fand die Angriffsketten.

Die statische Analyse fand die Schwachstellen, doch erst Live-Angriffstests bewiesen, wie sie sich zu Angriffen verketten lassen. Ein Vergleich von Evo COS, Claude Security und Claude Code Security.

feature insights context
Blog

Autonome Angriffe sind bereits Realität. Die Verteidigung muss Schritt halten.

Autonome Angreifer verkürzen das Zeitfenster für die Verteidigung. Erfahren Sie, wie kontinuierliches Erkennen, Beheben, Validieren und Verhindern Sicherheitsteams helfen kann, Schritt zu halten.

Blog

Ihr Schwachstellen-Backlog ist keine technische Schuld mehr, sondern eine Angriffsfläche

Ein wachsender Schwachstellen-Backlog ist mehr als eine technische Altlast: Er ist eine Angriffsfläche. Erfahren Sie, warum veraltete Risikoeinschätzungen, automatisierte Angreifer und verkettete Findings einen neuen Ansatz erfordern.