Unsichere npm-Standardkonfigurationen zum Stehlen von macOS-Tastaturkurzbefehlen nutzen
28. Juni 2023
0 Min. LesezeitBösartige npm-Pakete und ihre Gefahren sind ein häufig diskutiertes Thema – ob es nun um Hunderte Command-and-Control-Malwarepakete mit Cobalt Strike, Typosquatting oder allgemein um im npm-Register veröffentlichte Malware geht (auch bei PyPI und anderen). Um Entwickler und Maintainer dabei zu unterstützen, sich gegen diese Sicherheitsrisiken zu wappnen, hat Snyk einen Leitfaden zu Best Practices für npm-Sicherheit veröffentlicht.
Der folgende Angriff, auf den Yagiz Nizipli langjährige Maintainer aufmerksam gemacht hat, und das reale Risiko einer Datenkompromittierung zeigen, wie wichtig es ist, das Risiko der Ausführung beliebiger Befehle mit Paketmanagern zu minimieren – etwa über npm-postinstall-Lifecycle-Hooks.
Lifecycle-Skripte von npm
Der Node Package Manager (npm) stellt Entwicklern und Paket-Maintainern eine Reihe von Skripten zur Verwaltung der Lifecycle-Ereignisse eines Pakets bereit. Diese Skripte bieten Entwicklern großen Mehrwert, da sie verschiedene Aufgaben oder Konfigurationen als Teil des Paketinstallationsprozesses ausführen können. Mit postinstall-Skripten können Entwickler beispielsweise Aufgaben wie das Erstellen von Assets, das Einrichten von Umgebungsvariablen, das Ausführen von Migrationen oder andere Aufgaben automatisieren.
Die Eigenschaft scripts einer Datei package.json legt die Befehle fest, die durch den Lifecycle des Pakets und den des von Ihnen entwickelten Pakets ausgelöst werden. Derzeit unterstützt npm in jeder Eigenschaft scripts einer Datei package.json eine begrenzte Anzahl von Lifecycle-Skripten.
Der Einfachheit halber konzentriert sich der Rest dieses Artikels auf den Befehl postinstall. Die hier beschriebenen Konzepte gelten jedoch auch für andere Lifecycle-Abläufe.
Frühere Sicherheitsvorfälle
Mehrere aufsehenerregende Vorfälle hatten konkrete Auswirkungen auf JavaScript-Entwickler, darunter:
Der Sicherheitsvorfall bei cross-env, den Oscar Bolmsten aufdeckte.
Der gezielte Angriff über event-stream auf Entwickler von Kryptowährungsanwendungen.
Viele weitere Sicherheitsvorfälle rund um JavaScript und Node.js sind im Repository Awesome Node.js Security zusammengestellt.
Sicherheit gespeicherter Daten
Sicherheitsexperten bezeichnen den Schutz von Daten, die gespeichert sind oder ruhen, als Data-at-rest-Sicherheit. Damit wird sie vom Schutz während der Übertragung oder Verarbeitung abgegrenzt. Im Mittelpunkt steht der Schutz vertraulicher Informationen in Datenbanken, Dateisystemen oder persistenten Speichern. Data-at-rest-Sicherheit soll unbefugten Zugriff, Offenlegung und Manipulation verhindern, solange die Daten ruhen. Zu den Maßnahmen, mit denen sich gespeicherte Daten schützen lassen, gehören:
Entschlüsselung bei Bedarf: Entschlüsseln Sie nur die Daten, die für die aktuelle Aufgabe benötigt werden, und speichern Sie alle übrigen Daten verschlüsselt, um unbefugten Zugriff zu verhindern.
Zugriffskontrolllogik: Prüfen Sie die Identität der anfragenden Person über ein Verfahren wie ein Passwort, Zwei-Faktor-Authentifizierung oder biometrische Daten, die das Betriebssystem bereitstellt (z. B. FaceID). So lässt sich der Zugriff auf die Ressource für Unbefugte einschränken.
Die Angriffsfläche von Entwicklern
Best Practices der Branche geben vor, dass wir bei der Anwendungsentwicklung bestimmte Prinzipien befolgen. Diese Best Practices bieten viele Vorteile bei der Zusammenarbeit verschiedener Teams und Entwickler, vergrößern aber auch die Angriffsfläche.
Welche Daten liegen unverschlüsselt auf dem Rechner von Entwicklern?
Umgebungsvariablen in einfachen Textdateien wie
.env(über das Paketdotenvverfügbar).Projektkonfigurationsdateien im JSON-Format, zum Beispiel
config.json.SSH-Schlüssel für den Zugriff auf Github/Gitlab, die im Ordner
~/.sshliegen.Und … macOS-Tastaturkurzbefehle!
Textersetzungen unter macOS
macOS bietet standardmäßig eine Funktion namens Text Replacements, die in der Systemeinstellungen-App zu finden ist. Damit können Benutzer schnell ein Wort durch ein anderes ersetzen. Erst kürzlich habe ich erfahren, dass ein Entwickler bei einem bekannten Unternehmen Textersetzungen nutzte, um das Schlüsselwort @card durch seine Kreditkartendaten zu ersetzen. Auch wenn eine Kreditkartennummer ohne Ablaufdatum oder CVV allein keinen Zugriff auf Ihr Geld ermöglicht, schafft sie dennoch eine Angriffsfläche, die ausgenutzt werden kann.

Tastatur-Textersetzungen ausleiten
Tastaturkurzbefehle werden unter defaults gespeichert, das einer dateisystemgestützten .plist-Datei in einem lokalen Ordner entspricht. Mit dem folgenden Befehl werden Ihre konfigurierten Textersetzungen ausgegeben, die auch in der Systemeinstellungen-App verfügbar sind.
Beachten Sie, dass für den folgenden Code keine sudo-Berechtigungen erforderlich sind und jeder Prozess auf Ihrem Computer ihn ausführen kann.
Derselbe Befehl lässt sich in Node.js über execSync ausführen und ganz einfach mit dem vom Paketmanager npm unterstützten Lifecycle-Ablauf postinstall verarbeiten.
Das folgende Beispiel zeigt ein Node.js-Skript, mit dem Angreifer Textersetzungen unter macOS auslesen und vertrauliche Daten ausleiten können:
Damit der obige Code bei der Installation dieses Pakets ausgeführt wird, aktualisieren wir die Paketmanifestdatei package.json wie folgt:
Wird diese Bibliothek über npm verteilt und von einem Entwickler heruntergeladen, führt sie unser benutzerdefiniertes Skript direkt aus, um die Tastatur-Textersetzungen abzurufen und zu verarbeiten. Wenn Sie nicht aufpassen, übersehen Sie leicht die Zeile mit > node ./retrieve.js.
Schutzmaßnahmen
Was können Sie als Entwickler tun, um die Sicherheitsrisiken durch bösartige npm-Pakete und die allgemeinen Risiken der Ausführung beliebiger Befehle durch Pakete in Ihrem Abhängigkeitsbaum zu mindern?
Skripte bei der Installation von npm-Paketen ignorieren
Sie können sich vor Paketen schützen, die postinstall-Skripte nutzen. npm bietet beim Installieren von Paketen die Konfigurationsoption --ignore-scripts.
Sichere npm-Standardeinstellungen verwenden
Der npm-Paketmanager verfügt außerdem über eine Konfigurationsdatei namens .npmrc. Sie können die Standardeinstellungen über die npm-CLI ändern, um sicherere Voreinstellungen zu gewährleisten:
Sichere Speicherung
Am wichtigsten ist, dass Sie vertrauliche Informationen niemals im Klartext speichern. Wenn Sie sie aufgrund anderer Anforderungen dennoch im Klartext speichern müssen, sollten Sie den Zugriff auf die Ressource immer durch Multi-Faktor-Authentifizierung schützen.
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.
