PHP kennt nicht weniger als fünf Mechanismen, um externe Kommandos (z. B. Unix-Shellbefehle) von PHP aus zu starten. Alle diese Mechanismen können zu einem Sicherheitsrisiko werden, wenn man Benutzereingaben Bestandteil der ausgeführten Kommandos oder Dateinamen werden lässt.
Durch Anwendung der Funktion EscapeShellCmd() kann man das Risiko etwas vermindern (etwa: system(escapeshellcmd($cmd))). Dennoch empfiehlt es sich, die Parameter, die in die Gestaltung von $cmd eingehen, sorgfältig zu prüfen.
Externe Kommandos werden bei Verwendung von CGI PHP unter der Identität des CGI-Wrappers ausgeführt, bei Verwendung einer Modulversion von PHP mit der Identität des Webservers (siehe auch Webserver verstehen und tunen von Kristian Köhntopp).
Will man ein externes Kommando einfach nur ausführen, kann man das betreffende Kommando einfach in Backticks setzen:
`touch yyy`;
Dies wird im selben Verzeichnis wie das PHP-Script die Datei yyy erzeugen, falls der Webserver dort Schreibrecht hat.
Alternativ kann man ein Kommando durch die Funktion exec() starten lassen. Auch hier ist die Ausgabe nicht sichtbar, kann aber in einem Array abgelegt werden:
exec("cat /etc/group", $lines, $result); echo "result = $result<br>"; echo "Lines<br>\n"; foreach ($lines as $k => $v) { echo "k=$k v=$v<br>\n"; }
Die Ausgabe des Befehls wird im Feld $lines zur Verfügung gestellt, der Exitcode des Befehls in $result.
Die Funktion system() gibt die Ausgabe des Unix-Kommandos dagegen an den Webserver weiter. Ebenso passthru():
system("ls -l", $result); echo "Result: $result<br>\n"; passthru("ls -l", $result); echo "Result: $result<br>\n";
Schließlich kann man externe Kommandos noch mit Hilfe der Funktion popen() starten:
$fp = popen("ls -l", "r"); while($line = fgets($fp, 1024)) { printf("%s<br>\n", $line); }
Im safe_mode unterliegt die Programmausführung weiteren Einschränkungen.






