Start · Sprachen · PHP · Referenz · escapeshellcmd

escapeshellcmd

Funktion

Maskiert Shell-Metazeichen in einem Befehlsstring, um die Ausführung unbeabsichtigter Shellbefehle zu verhindern.

seit PHP 4.0.0 Kategorie: misc

Signatur

escapeshellcmd(string $command): string

Beschreibung

escapeshellcmd() maskiert alle Zeichen in einem String, die von einer Shell als Sonderzeichen interpretiert werden könnten. Dazu gehören unter anderem: #&;`|*?~<>^()[]{}$\, Newlines sowie nicht kodierte Null-Bytes. Auf Windows-Systemen werden zusätzlich %-Zeichen maskiert.

Die Funktion ist dafür gedacht, einen vollständigen Befehl (inklusive Argumente) zu schützen, bevor er an Funktionen wie exec(), system(), shell_exec() oder passthru() übergeben wird. Soll hingegen nur ein einzelnes Argument maskiert werden, ist escapeshellarg() die bessere Wahl.

Wichtig: escapeshellcmd() erlaubt es dem Benutzer weiterhin, eine beliebige Anzahl von Argumenten an den Befehl zu übergeben. Wird benutzerkontrollierte Eingabe in den Befehlsstring eingebettet, bietet die Funktion alleine keinen vollständigen Schutz — in solchen Fällen sollte escapeshellarg() für jedes einzelne Argument verwendet werden.

Die Funktion arbeitet zeichenbasiert und ist nicht kontextabhängig, d. h. sie unterscheidet nicht zwischen Befehlsnamen und Argumenten. Für eine robuste Absicherung empfiehlt es sich, Shell-Aufrufe mit Benutzereingaben grundsätzlich zu vermeiden oder durch andere Mechanismen (z. B. Whitelisting) zu ergänzen.

Parameter

Name Typ Default Beschreibung
$command Pflicht string Der Befehlsstring, in dem Shell-Metazeichen maskiert werden sollen. Typischerweise ein vollständiger Shell-Befehl inklusive Programmpfad und Argumente.

Rückgabewert

Typ
string
Beschreibung
Gibt den übergebenen String zurück, in dem alle Shell-Metazeichen mit einem Backslash (\) maskiert wurden (auf Windows werden einzelne Zeichen in doppelte Anführungszeichen eingeschlossen).

Beispiele

Einfaches Maskieren eines Shell-Befehls

<?php
$userInput = 'hello; rm -rf /';
$cmd = escapeshellcmd('echo ' . $userInput);
echo $cmd . PHP_EOL;

// Ausführung (nur zur Demo):
$output = shell_exec($cmd);
echo $output;
echo hello\; rm\ -rf\ / hello; rm -rf /

Kombination mit escapeshellarg für einzelne Argumente

<?php
// Benutzereingabe: Dateiname
$filename = $_GET['file'] ?? 'test.txt'; // z.B. 'test.txt; cat /etc/passwd'

// Nur ein Argument sicher maskieren:
$safeArg = escapeshellarg($filename);

// Den gesamten Befehl mit escapeshellcmd schützen:
$cmd = escapeshellcmd('/usr/bin/cat ' . $safeArg);
echo 'Ausgeführter Befehl: ' . $cmd . PHP_EOL;

$output = shell_exec($cmd);
echo htmlspecialchars($output);
Ausgeführter Befehl: /usr/bin/cat 'test.txt; cat /etc/passwd'

// Wichtig · Fallstricke

Sicherheitshinweis: escapeshellcmd() schützt nicht vor der Übergabe zusätzlicher unerwünschter Argumente. Ein Angreifer kann z. B. durch Leerzeichen zusätzliche Argumente an das Programm übergeben, was bei manchen Programmen (z. B. find, tar) gefährlich sein kann. Verwende daher escapeshellarg() für jedes benutzerkontrollierte Argument separat.

Windows vs. Unix: Das Maskierungsverhalten unterscheidet sich leicht zwischen den Betriebssystemen. Auf Windows werden z. B. auch %-Zeichen (Umgebungsvariablen) behandelt. Code, der auf beiden Plattformen laufen soll, sollte sorgfältig getestet werden.

Allgemeiner Rat: Shell-Aufrufe mit Benutzerdaten sind grundsätzlich risikobehaftet. Wo immer möglich, sollte auf systemeigene PHP-Funktionen oder Bibliotheken zurückgegriffen werden, die keine Shell benötigen.