Vor ein paar Monaten habe ich ein Projekt namens bösartige Pakete (auch bekannt als "bösartige Pakete") gestartet. Es überwacht Aktualisierungen im npm-Repository, lädt alle neuen Module herunter und überprüft sie dann auf Läuse - es sucht nach Netzwerkaktivitäten, verdächtigen Vorgängen mit dem Dateisystem usw. Selbst kleine Projekte auf node.js haben häufig einen großen Abhängigkeitsbaum, und Entwickler haben physisch keine Möglichkeit, sie alle zu testen. Dies gibt Angreifern einen enormen Handlungsspielraum, und es stellt sich die Frage, wie viel böse Registrierung sich in den dunklen Ecken der npm-Registrierung versteckt. 180.000 geprüfte Pakete später bekam ich eine grobe Antwort.

Und diese Antwort - vielleicht nicht so sehr.
[Anmerkung: Auf Medium gibt es eine englische Version dieses Artikels, auch von meiner Autorschaft]
Was kann ein npm-Paket mit Ihrem System tun?
Das Paket kann auf zwei Arten Schaden anrichten - bei der Installation / Deinstallation und zum Zeitpunkt des Starts Ihrer Anwendung. Schauen wir uns beide Optionen anhand von Beispielen an.
Mit NPM-Skripten können Pakete zum Zeitpunkt der Installation und Deinstallation beliebige Befehle ausführen. Dazu gehören postinstall
, install
, postinstall
, preuninstall
und postuninstall
, die von npm zum richtigen Zeitpunkt im postuninstall
automatisch ausgeführt werden. Was können sie tun? Trotzdem kann Ihr aktueller Benutzer alle Ihre Fotos aus dem letzten Urlaub löschen oder Ihren Browserverlauf mit dem FBI zusammenführen (obwohl er ihn höchstwahrscheinlich bereits hat). Dieses Verhalten kann deaktiviert werden, indem das --ignore-scripts
wird. Erstens tut dies niemand, und zweitens können Sie auf diese Weise eine Reihe recht zuverlässiger Pakete auflösen. Über Skripte wurde der sensationelle Angriff auf ESLint ausgeführt, der Benutzer von eslint-scope (6 Millionen Installationen pro Woche) und eslint-config-eslint (zweitausend Installationen pro Woche) betraf .
Das Paket erhält eine zweite Chance, Ihr Leben während der Initialisierung zu verkomplizieren (tritt normalerweise beim ersten require
Aufruf auf). Jetzt hat er die Möglichkeit, globale Variablen und andere Pakete zu ändern, um beispielsweise den privaten Schlüssel aus Ihrer Bitcoin-Brieftasche zu stehlen oder die crypto.randomBytes
Methode nicht so zufällig zu machen .

Wie viele Schadpakete wurden erkannt?
Nun, die Liste kann nicht als beeindruckend bezeichnet werden. Insgesamt wurden 3 Pakete gefunden, die durch die Bemühungen des npm-Sicherheitsteams aus dem npm-Repository entfernt wurden. Lassen Sie uns darüber nachdenken:
- Commander-js versucht, sich als echte
commander.js
zu verkleiden ( https://www.npmjs.com/package/commander ), enthält jedoch ein ungewöhnliches Detail, nämlich ein postinstall
Skript, das den Inhalt von http://23.94.46.191/ herunterlädt und postinstall
update.json (enthält zum Zeitpunkt der Veröffentlichung nichts Kriminelles). Sicherheitshinweis: https://www.npmjs.com/advisories/763 . - rrgod lädt das Skript über dieselben Skripte von http://static.ricterz.me herunter und führt es aus, wodurch wiederum versucht wird, ein anderes Skript zu laden, das derzeit nicht verfügbar ist. Sicherheitshinweis: https://www.npmjs.com/advisories/764 .
- portionfatty12 kann nicht als vollständig bösartig bezeichnet werden, aber die Art und Weise, wie der Autor Statistiken über die Einstellungen seiner Idee sammelt, ist sehr zweifelhaft. Dadurch wird Ihr öffentlicher SSH-Schlüssel (
~/.ssh/id_rsa.pub
) an einen Server gesendet, der derzeit nicht verfügbar ist. Sicherheitshinweis: https://www.npmjs.com/advisories/765 .
Trotz der sehr bescheidenen Ergebnisse wurden bei der Analyse aller verdächtigen Pakete (und ich habe mir mehr als 3000 Berichte angesehen, um diese drei Perlen zu finden) viele lustige und nicht sehr Dinge gefunden, an die Sie normalerweise nicht denken (oder sorgfältig versuchen, nicht darüber nachzudenken), indem Sie npm install
eingeben . Stellen Sie sich also vor, Sie wählen versehentlich eines der vielen Pakete aus dem Repository aus und installieren es. Was könnte schief gehen?
1. Ein Paket kann Methoden in anderen Paketen überschreiben (einschließlich der aus der Standardlieferung von Node.js).
Wenn Sie jedoch einige frühere Absätze gelesen haben oder seit mehr als einer Woche mit dem Javascript-Ökosystem arbeiten, ist dies wahrscheinlich keine Neuigkeit für Sie. Aber das Ausmaß dieser Katastrophe könnte sich Ihnen entziehen. Wenn Ihr Projekt also mindestens einige Abhängigkeiten aufweist, ist es höchstwahrscheinlich die Methode fs.closeSync , die Sie bereits überschrieben haben (und möglicherweise mehr als einmal). Eine große Anzahl von Paketen ändert die API eines anderen, aber nur wenige von ihnen haben zumindest einen guten Grund dafür. Zu den „Champions“ gehört Graceful-Fs mit 12 Millionen Installationen pro Woche, die Dutzende von Methoden aus Fs neu definieren . Es ist auch erwähnenswert, dass der Async-Listener 46 verschiedene Methoden überschreibt, einschließlich der unglückseligen crypto.randomBytes
, die mich ein wenig störten, als ich dies zum ersten Mal entdeckte.
Stellen Sie sich vor, wie ein Fehler aussehen würde, der durch eine solche Überschreibung aufgrund einer Abhängigkeit in den Tiefen der Hierarchie verursacht wird. Es gibt jedoch keinen Grund zur Sorge, denn ...
2. Das Paket kann die geänderte API bestimmen, um zusätzliche Korrekturen daran vorzunehmen

Ja, einige Pakete tun dies (meistens in Bezug auf die gleichen /graceful-fs/.test(fs.closeSync.toString())
) unter Verwendung der Wunder der Akrobatik wie /graceful-fs/.test(fs.closeSync.toString())
. Wenn Sie also plötzlich auf unverständliche Probleme in der Standardbibliothek stoßen, installieren Sie einfach ein paar zufällige npm-Pakete. Oder schalten Sie einfach den Computer aus und machen Sie einen Spaziergang im nächsten Park. Das Leben ist zu kurz, um all dies zu verstehen.
3. Er kann Analysen senden
Adblock schützt Sie nicht, wenn in der Konsole etwas passiert, und die Autoren einiger Pakete verwenden dies erfolgreich. Einige senden die grundlegendsten Informationen, wie z. B. ecdsa-csr :
Einige sind nicht so schüchtern. Hier ist beispielsweise ein Teil des serverlosen Berichts (das Original ist zweimal größer):
Glücklicherweise jquery
keine Statistiken, sodass Sie diese weiterhin geheim von allen installieren können. Vorerst.
4. Ihr Computer kann anstelle eines CI / CD-Servers verwendet werden
Warum sollten Sie Ihr Paket kompilieren, wenn Ihre Benutzer dies während der Installation tun können ? Sie können eine zusätzliche Leistung erhalten, wenn Sie nur die Hauptversion des erforderlichen Compilers angeben, z. B. typescript@3
. Eine Hoffnung für die gebildeten Leute von Microsoft, die wissen, wie man das richtige Semver macht.
Kann man noch weiter gehen? Natürlich !
"postinstall": "eslint --ext .js,.vue --fix src"
Jetzt können Sie ruhig schlafen - alle Benutzer erhalten perfekt formatierte Quellen für Ihr Paket.
5. Er könnte versuchen, dich zu erschrecken.

Wenn Sie die ganze Serie gesehen haben, Mr. Roboter, aber immer noch nicht motiviert genug, Computernetzwerke zu lesen und etwas wirklich Beeindruckendes zu tun, das heißt eine einfache Lösung - demonstrieren Sie der Welt Ihre Fähigkeiten durch ein paar Zeilen in einem postinstall
. Genau das hat der Autor von Pizza-Pasta getan (und mir gleichzeitig KDPV vorgestellt).
{ "name": "pizza-pasta", "author": "Zeavo", "scripts": { "install": "mkdir -p ~/Desktop/hacked && touch ~/Desktop/hacked/pwnddddd && wget https://imgur.com/download/KTDNt5I -P ~/Desktop/hacked/", "postinstall": "find ~/.ssh | xargs cat || true && printf '\n\n\n\n\n\nOH HEY LOOK SSH KEYS\n\n\n\nHappy Birthday! Youve been h4ck0red\n\n\n'" } }
6. Das Paket kann Bash-Skripte laden und ausführen
Haben Sie gehört, dass curl|bash
keine gute Idee ist ? Wenn nicht, sind Sie möglicherweise ein ORESoftware- Mitarbeiter, der eine ganze Reihe von Paketen mit ähnlichen Zeilen in einem postinstall
:
curl --silent -o- https://raw.githubusercontent.com/oresoftware/realpath/master/assets/install.sh | bash
Bisher enthält dieses Skript nichts Kriminelles ... Im Moment. Ich hoffe, dass jeder, der Zugang zu master
in oresoftware/realpath
hat, äußerst ehrliche und anständige Menschen sind.
7. Möglicherweise werden Sie nach einem Passwort gefragt
Der Autor von magicleap hat eine ziemlich ungewöhnliche Methode gefunden, um ein privates Paket über ein öffentliches Repository zu verteilen. Sein Projekt besteht aus einem verschlüsselten Archiv und Dienstprogrammen zum Entschlüsseln - aber nur, wenn Sie den richtigen Schlüssel in die Umgebungsvariable MAGICLEAP
:
8. Das Paket kann sich während der Installation selbst patchen
Der Autor der gefälschten Vorlage hat keine Zeit, die Tests vom unmittelbaren Code zu trennen, zumal dies einfach durch Hinzufügen eines speziellen Kommentars am Ende der Testzeilen möglich ist:
Und dann löschen Sie sie durch sed
:
"postinstall": "sed -i '/\\/\\/ TEST/d' index.js"
Einfach und elegant!
9. Das Paket kann die npm
Einstellungen ändern
Meiner bescheidenen Meinung nach ist package-json.lock
eine großartige Sache, die vor einer ganzen Reihe von Problemen bewahren kann, die durch die Nachlässigkeit anderer Entwickler verursacht werden. Einige Gegner dieser Idee haben jedoch recht gute Argumente gegen:
"preinstall": "npm config set package-lock false"
10. Er kann den Hintergrund Ihres Desktops auf einem Foto von Nicolas Cage ändern

Hier ist ein Link für alle Fälle - https://www.npmjs.com/package/cage-js . Vielleicht hat es sich gelohnt, dieses Paket als bösartig zu registrieren.
11. Das Paket kann Sie überrollen
Dies ist, was Ember-Data-React bewirkt und das berühmte Video während der Installation öffnet. Leider ist es nicht möglich, mit seiner Hilfe Daten von Ember nach React zu übertragen - es enthält keine einzige Zeile Javascript-Code.
12. Es kann einfach nicht installiert werden.

Nicht vorhandene Abhängigkeiten, falsch angegebene Versionen, private Repositorys, die in Vergessenheit geraten sind - Sie können nicht etwa 0,6% aller Pakete aus dem npm-Repository installieren.
Anstelle einer Schlussfolgerung
NPM-Pakete können seltsame Dinge mit Ihrem System tun, und Sie haben nicht viele Möglichkeiten, sich davor zu schützen. Verwenden Sie package-lock.json
, um plötzliche Aktualisierungen zu vermeiden (und stellen Sie sicher, dass niemand die Verbindung ohne Ihr Wissen trennt). Konfigurieren Sie CSP im Frontend so, dass die Hintertür im Modul eines Drittanbieters nicht mindestens Daten mit dem Autor zusammenführen kann. Und sichern Sie Ihre Fotos für alle Fälle.
Wenn Sie das Gefühl haben, genug Kraft zu haben, um in die wunderbare Welt der npm-Pakete einzutauchen, finden Sie alle Quellen hier: https://github.com/malicious-packages/core . Das Dienstprogramm ist voll von Hacks und nicht optimalen Lösungen, aber es bewältigt seine Aufgabe. Es gibt auch einen MongoDB-Speicherauszug im Repository mit den Analyseergebnissen von mehr als 180.000 Paketen. Vergessen Sie vor allem nicht, den Filter {'reports.status': 'unverified'}
hinzuzufügen. Ich habe aus Zeitgründen nicht mehr vor, dieses Projekt zu entwickeln, aber ich werde versuchen, bei allen Fragen und Problemen zu helfen, falls vorhanden.
Pass auf dich und deine Anwendungen auf!