12 seltsame Dinge, die nach der Installation des npm-Pakets passieren können

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.


Bild


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 .


Bild


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:



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


Bild


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 :


 // POST https://api.therootcompany.com/api/therootcompany.com/public/ping { "package":"ecdsa-csr", "version":"1.1.1", "node":"v10.14.2", "arch":"x64", "platform":"linux", "release":"4.9.125-linuxkit", "action":"install", "ppid":"eDSeYr9XUNRi9WhWli5smBNAvdw=" } 

Einige sind nicht so schüchtern. Hier ist beispielsweise ein Teil des serverlosen Berichts (das Original ist zweimal größer):


 // POST https://tracking.serverlessteam.com/v1/track { "userId":"0e32cba0-14ef-11e9-9f89-b7ed4ca5dbba", "event":"framework_stat", "properties":{ "version":2, "general":{ "userId":"0e32cba0-14ef-11e9-9f89-b7ed4ca5dbba", "context":"install", "timestamp":1547135257977, "timezone":"GMT+0000", "operatingSystem":"linux", "userAgent":"cli", "serverlessVersion":"1.35.1", "nodeJsVersion":"v10.14.2", "isDockerContainer":true, "isCISystem":false, "ciSystem":null } } } 

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.


Bild


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 :


 // : https://github.com/modulesio/magicleap/blob/master/decrypt.js var key = process.env['MAGICLEAP']; console.warn('Decrypting magicleap module with MAGICLEAP environment variable'); const ws = fs.createReadStream(path.join(__dirname, 'lib.zip.enc')) .pipe(crypto.createDecipher('aes-256-cbc', Buffer.from(key, 'base64'))) .pipe(fs.createWriteStream(path.join(__dirname, 'lib.zip'))); 

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:


 // : https://github.com/framp/fake-template/blob/master/index.js const template = (string, tag=defaultTag) => { if (mode !== 'literal') throw new Error('Invalid template') return (context={}) => tag(literals, ...expressions.map(evalInContext(context))) } assert.equal(template('')(), ``) // TEST assert.equal(template('abc')(), `abc`) // TEST const dog = 'Orlando' // TEST assert.equal(template('abc ${dog} lol ${cat}')({dog}), `abc ${dog} lol ${cat}`) // TEST 

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


Bild


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.


Bild
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!

Source: https://habr.com/ru/post/de436132/


All Articles