In diesem Artikel lernen wir, wie Sie Systembefehle mit Node.js korrekt aufrufen, um die Schwachstellen für die Injektion von Befehlszeilen zu vermeiden.
Die Methode, mit der wir häufig Befehle aufrufen, ist die einfachste child_process.exec. Es hat ein sehr einfaches Verwendungsmuster; Es gibt einen String -Befehl über und gibt einen Fehler oder eine Befehlsverarbeitungsergebnis an die Rückruffunktion zurück.
Hier finden Sie ein sehr typisches Beispiel für Ihre Aufrufsystembefehle über child_process.exec.
Die Codekopie lautet wie folgt:
chirt_process.exec ('ls', function (err, data) {
console.log (Daten);
});
Was passiert jedoch, wenn Sie dem von Ihnen aufgerufenen Befehl einige benutzergeführte Parameter hinzufügen müssen? Die offensichtliche Lösung besteht darin, den Benutzer direkt mit Ihrem Befehl einzugeben. Meine jahrelange Erfahrung sagt mir jedoch: Wenn Sie vernetzte Zeichenfolgen von einem System an ein anderes senden, wird es eines Tages Probleme geben.
Die Codekopie lautet wie folgt:
var path = "Benutzereingabe";
Child_process.exec ('ls -l' + Pfad, Funktion (err, data) {
console.log (Daten);
});
Warum hat die Verbindungszeichenfolge Probleme?
Nun, denn unter der Engine von Child_Process.exec wird die Ausführung von "/bin/sh" aufgerufen. Nicht das Zielprogramm. Der gesendete Befehl wird gerade an einen neuen "/bin/sh" -Prozess übergeben, um die Hülle auszuführen. Der Name von child_process.exec ist etwas irreführend - dies ist ein Bash -Interpreter, kein Programm. Dies bedeutet, dass alle Shell -Zeichen verheerende Konsequenzen haben können, wenn die vom Benutzer eingegebenen Parameter direkt ausgeführt werden.
Die Codekopie lautet wie folgt:
[PID 25170] execve ("/bin/sh", ["/bin/sh", "-c", "ls -l Benutzereingabe"], [/ * 16 vars */]
Zum Beispiel könnte ein Angreifer ein Semikolon verwenden ";" Um den Befehl zu beenden und einen neuen Anruf zu starten, können sie Backticks oder $ () verwenden, um den Unterbefehl auszuführen. Es gibt auch viele potenzielle Missbräuche.
Was ist der richtige Weg, um es zu nennen?
Execfile / Spawn
Spawn und Execfile nehmen einen zusätzlichen Array -Parameter, bei dem es sich nicht um eine Shell -Umgebung handelt, die andere Befehle ausführen kann und keine zusätzlichen Befehle ausführt.
Verwenden wir Execfile und Spawn, um das vorherige Beispiel zu ändern, um festzustellen, wie sich die Systemaufrufe unterscheiden und warum es nicht anfällig für Befehlsinjektion ist.
Child_process.execfile
Die Codekopie lautet wie folgt:
var child_process = required ('child_process');
var path = "."
Child_process.execfile ('/bin/ls', ['-l', Path], Funktion (Err, Ergebnis) {
console.log (Ergebnis)
});
Auslaufsystemanrufe
Die Codekopie lautet wie folgt:
[PID 25565] execve ("/bin/ls", ["/bin/ls", "-l", "."], [/ * 16 vars */]
Child_process.Spawn
Beispiele für die Verwendung von Spawnersatzen sind sehr ähnlich.
Die Codekopie lautet wie folgt:
var child_process = required ('child_process');
var path = "."
var ls = child_process.spawn ('/bin/ls', ['-l', Pfad])
ls.stdout.on ('Daten', Funktion (Daten) {
console.log (data.toString ());
});
Auslaufsystemanrufe
Die Codekopie lautet wie folgt:
[PID 26883] execve ("/bin/ls", ["/bin/ls", "-l", "."], [/ * 16 vars */
Bei Verwendung von Spawn oder Execfile ist es unser Ziel, nur einen Befehl (Parameter) auszuführen. Dies bedeutet, dass der Benutzer den injizierten Befehl nicht ausführen kann, da /bin /ls nicht weiß, wie Backticks oder Rohre oder Rohr oder;. Was seine /bin /bash erklären wird, sind die Parameter dieser Befehle. Es ähnelt der Verwendung eines Parameters, um Parameter in eine SQL -Abfrage zu übergeben, wenn Sie damit vertraut sind.
Es gibt aber auch eine Warnung: Die Verwendung von Spawn oder Execfile ist nicht immer sicher. Zum Beispiel kann das Ausführen /Bin /Finden und Übergeben von Benutzereingabeparametern dazu führen, dass das System eingeschlossen wird. Der Befehl find enthält einige Optionen, mit denen das Lesen/Schreiben von willkürlichen Dateien ermöglicht wird.
Hier finden Sie einige Anleitungen zu Node.js, die Systembefehle ausführen:
Vermeiden Sie es mit Child_process.exec, insbesondere wenn Sie vom Benutzer eingegebene Parameter einschließen müssen, bitte denken Sie daran.
Versuchen Sie nicht, die Benutzer Parameter übergeben zu lassen. Die Verwendung von Auswahlmöglichkeiten ist viel besser als die direkten Eingabe von Benutzern direkt.
Wenn Sie dem Benutzer erlauben müssen, Parameter einzugeben, siehe die Parameter des Befehls ausführlich, bestimmen Sie, welche Optionen sicher sind, und erstellen Sie eine Whitelist.