Leitlinien

Befehlsinjektion

Betrachten wir zunächst die Command Injection an sich. Wir werden uns vor allem auf einige Beispiele konzentrieren, um zu sehen, wie es in Aktion aussieht. Zur Auffrischung: Command Injection-Schwachstellen treten auf, wenn Benutzereingaben einen Teil eines Betriebssystembefehls verwenden, wie die folgende Funktion:

let ip = request.params.ipAddress;

system("ping " + ip);

Wenn ein Benutzer die IP-Adresse angibt, nehmen wir `8.8.8.8` als Beispiel, wird der Befehl `ping 8.8.8.8` ausgeführt, der genau das tut, was man erwarten würde. Wenn der Benutzer jedoch `8.8.8.8 && ls /etc/` angibt, wird dieser Befehl nicht nur die IP 8.8.8.8 anpingen, sondern auch `ls` im `/etc/ Ordner ausführen. 

Milderung

Angesichts der Schwere eines Befehlsinjektionsangriffs müssen Sie sich bei der Arbeit mit Systembefehlen zunächst einige wichtige Fragen stellen:

  • Ist es wirklich notwendig, diesen Befehl aufzurufen? Die beste Verteidigung ist, niemals Systembefehle aufzurufen
  • Gibt es Bibliotheken/Bindings, mit denen man den gleichen Effekt ohne Systembefehl erzielen kann?
  • Können Sie Daten über die Standard-Eingabe an den Prozess übergeben, anstatt über den Befehl selbst? 

Wenn diese Dinge nicht möglich sind, ist die Parametrisierung wichtig.

Beispiele

Hier sind einige Beispiele in verschiedenen Sprachen, um zu zeigen, wie dies in der Praxis aussieht. 

Ohne die Verwendung der Parametrisierung ist dies anfällig für Command Injection.

string folder = "/tmp/ && ifconfig";
string cmd = "\"ls " + folder +"\"";

// INSECURE: Führt sowohl den Befehl `ls` als auch `ifconfig` aus
System.Diagnostics.Process.Start("bash", "-c " + cmd);

C# - sicher

Durch die Bereitstellung des Befehls in Form einer Liste von Parametern wird der Befehl parametrisiert und gegen Command Injection geschützt.

string folder = "/tmp/ && ifconfig";
List<string> arguments = new List<string>() {"-c", "ls", folder}; 

// SECURE: Does not execute ifconfig command
System.Diagnostics.Process.Start("bash", arguments);

Java - Unsicher

Ohne die Verwendung der Parametrisierung ist dies anfällig für Command Injection.

String folder = "/tmp/ && ifconfig";

// INSECURE: Führt sowohl den Befehl `ls` als auch `ifconfig` aus
ProcessBuilder b = new ProcessBuilder("bash -c ls " + folder);

Process p = pb.start();

Java - Sicher

Durch die Bereitstellung des Befehls in Form einer Liste von Parametern wird der Befehl parametrisiert und gegen Command Injection geschützt.

String folder = "/tmp/ && ifconfig";

// SICHER: Führt den Befehl ifconfig nicht aus
ProcessBuilder b = new ProcessBuilder("bash", "-c", "ls", folder);

Process p = pb.start();

Javascript - Unsicher

Ohne die Verwendung der Parametrisierung ist dies anfällig für Command Injection.

const { exec } = require("child_process");

const folder = "/tmp/ && ifconfig";

// INSECURE: Executes both the `ls` and `ifconfig` command 
const ls = exec("bash -c ls " + folder, (error, stdout, stderr) => {
     console.log(`stdout: ${stdout}`);
});

Javascript - Sicher

const { spawn } = require("child_process");

const folder = "/tmp/ && ifconfig";

// SECURE: Does not execute ifconfig command
const ls = spawn("bash", ["-c", "ls", folder]);

ls.stdout.on("data", data => {
    console.log(`stdout: ${data}`);
});

Python - Unsicher

Ohne die Verwendung von Parametern ist dies anfällig für Command Injection.‍

import subprocess

folder = "/tmp/ && ifconfig"

# INSECURE: Führt sowohl den Befehl `ls` als auch `ifconfig` aus
subprocess.run("bash -c ls " + folder, shell=True)

Python - Sicher

Durch die Bereitstellung des Befehls als Liste von Parametern wird der Befehl parametrisiert und gegen Command Injection geschützt.

import subprocess

folder = "/tmp/ && ifconfig"

# SICHER: Führt den Befehl ifconfig nicht aus
subprocess.run(["bash", "-c", "ls", folder])