In diesem Artikel wird hauptsächlich die Methode zum sicheren Aufrufen von Systembefehlen in Node.js vorgestellt (um das Einschleusen von Sicherheitslücken zu vermeiden). In diesem Kapitel werden allgemein die Sicherheitsprobleme erläutert, die beim Verbinden von Zeichenfolgen auftreten können.
In diesem Artikel erfahren Sie, wie Sie Node.js korrekt zum Aufrufen von Systembefehlen verwenden, um häufige Schwachstellen bei der Befehlszeileninjektion zu vermeiden.
Die Methode, die wir häufig zum Aufrufen von Befehlen verwenden, ist die einfachste child_process.exec. Es verfügt über ein sehr einfaches Verwendungsmuster; durch die Übergabe eines Zeichenfolgenbefehls und die Rückübergabe eines Fehlers oder eines Befehlsverarbeitungsergebnisses an die Rückruffunktion.
Hier ist ein sehr typisches Beispiel für den Aufruf eines Systembefehls über child_process.exec.
child_process.exec('ls', function (err, data) { console.log(data); });
Was passiert jedoch, wenn Sie dem von Ihnen aufgerufenen Befehl einige vom Benutzer eingegebene Parameter hinzufügen müssen? Die offensichtliche Lösung besteht darin, die Benutzereingaben direkt mit Ihrem Befehl zusammenzuführen. Meine jahrelange Erfahrung sagt mir jedoch: Wenn man verbundene Strings von einem System zum anderen schickt, wird eines Tages etwas schief gehen.
var path = "user input"; child_process.exec('ls -l ' + path, function (err, data) { console.log(data); });
Warum gibt es ein Problem mit der Verbindungszeichenfolge?
Nun, denn unter der child_process.exec-Engine wird „/bin/sh“ aufgerufen und ausgeführt. und nicht das Zielprogramm. Der gesendete Befehl wird einfach an einen neuen „/bin/sh“-Prozess übergeben, um die Shell auszuführen. Der Name child_process.exec ist etwas irreführend – es handelt sich um einen Bash-Interpreter, der kein Programm startet verheerende Folgen haben, wenn vom Benutzer eingegebene Parameter direkt ausgeführt werden
[pid 25170] execve("/bin/sh", ["/bin/sh", "-c", "ls -l user input"], [/* 16 vars */]
Ein Angreifer kann beispielsweise ein Semikolon „;“ verwenden, um einen Befehl zu beenden und einen neuen zu starten. Er kann Backticks oder $ verwenden () um Unterbefehle auszuführen.
Was ist also der richtige Weg, um execFile/spawn aufzurufen? Führen Sie andere Befehle in einer Shell-Umgebung aus und führen Sie keine zusätzlichen Befehle aus.
Verwenden Sie execFile, um zu sehen, wie sich der Systemaufruf unterscheidet und warum er nicht anfällig für Befehlsinjektion ist. Der Systemaufruf
child_process.spawn
ist dem Beispiel mit Spawn-Ersetzung des Systemaufrufs, der ausführt, sehr ähnlich 🎜>Bei Verwendung von spawn oder execfile besteht das Ziel darin, nur einen Befehl (Parameter) auszuführen. Dies bedeutet, dass der Benutzer den injizierten Befehl nicht ausführen kann, da /bin/ls nicht weiß, wie er mit Backticks oder Pipes umgehen soll. . Was /bin/bash tun wird, ist die Verwendung von
var child_process = require('child_process'); var path = "." child_process.execFile('/bin/ls', ['-l', path], function (err, result) { console.log(result) });
[pid 25565] execve("/bin/ls", ["/bin/ls", "-l", "."], [/* 16 vars */]
Das Obige ist der gesamte Inhalt Weitere verwandte Tutorials finden Sie im Node.js-Video-Tutorial
!