Escapeshellarg: примеры (PHP)
escapeshellarg(string $arg): stringФункция escapeshellarg в PHP
Функция escapeshellarg() предназначена для безопасной передачи аргументов в команды командной оболочки (shell). Она заключает переданную строку в одинарные кавычки и экранирует все существующие в ней одинарные кавычки. Это предотвращает возможность внедрения и выполнения произвольных команд, делая работу с функциями вроде exec(), system() или shell_exec() более безопасной.
Функция принимает всего один обязательный параметр:
- $arg (string) – Строка, которая будет экранирована и подготовлена для использования в качестве аргумента командной строки.
Функция возвращает экранированную строку, заключенную в одинарные кавычки.
Примеры использования escapeshellarg
$file = "my file.txt";
echo escapeshellarg($file);'my file.txt'
$text = "Don't stop me now!";
echo escapeshellarg($text);'Don'\''t stop me now!'
$userInput = $_GET['filename']; // Например, "file'; rm -rf /; #"
$safeArg = escapeshellarg($userInput);
$command = "ls -la " . $safeArg;
echo $command;ls -la 'file'\''; rm -rf /; #'
Похожие функции в PHP
В PHP существуют и другие функции для работы с оболочкой и экранированием.
Функция escapeshellcmd() экранирует метасимволы командной строки, такие как &#; | ; > < * ? ~ < > ^ () [ ] { } $ \ \x0A \xFF. Она не экранирует пробелы и не заключает строку в кавычки. escapeshellarg считается более предпочтительной для экранирования отдельных аргументов, так как обеспечивает более надежную защиту.
Функция addslashes() экранирует специальные символы в строках (одинарные и двойные кавычки, обратный слэш) для использования в SQL-запросах или других контекстах. Она не предназначена для командной оболочки и не является адекватной заменой escapeshellarg.
Аналоги функции в других языках
import shlex
arg = "file's name.txt"
safe_arg = shlex.quote(arg)
print(safe_arg) # Вывод: 'file'\''s name.txt''file'\''s name.txt'
В Node.js безопасная передача аргументов обеспечивается за счет отдельного массива аргументов в spawn или execFile, что исключает необходимость ручного экранирования.
const { spawn } = require('child_process');
const ls = spawn('ls', ['-la', "file's name.txt"]); // Аргументы передаются отдельноSELECT QUOTE("Don't");'Don\'t'
MySQL QUOTE() возвращает строку, заключенную в одинарные кавычки, с экранированными специальными символами, но предназначена она для SQL, а не для shell.
Типичные ошибки
// Неправильно
$command = escapeshellarg("ls -la /home");
exec($command); // Попытается выполнить 'ls -la /home' как имя команды$arg = "test'file";
$safe1 = escapeshellarg($arg); // 'test'\''file'
$safe2 = escapeshellarg($safe1); // ''\''test'\'''\'''\''file'\'''
exec("echo " . $safe2); // Выведет строку с лишними кавычками'test'\''file'
Функция escapeshellarg не предназначена для экранирования имени самой команды или пути к ней. Ее следует применять только к аргументам.
Изменения в последних версиях PHP
В PHP 8.0 поведение функции escapeshellarg было изменено на более строгое: теперь функция преобразует все не-ASCII-байты и символы NUL в их восьмиричное представление (например, символ © превращается в \342). Это улучшает кросс-платформенную совместимость, особенно на системах Windows, где кодировка командной строки может отличаться. Также в PHP 8.0 функция теперь выбрасывает TypeError, если ей передать аргумент, не являющийся строкой, в то время как ранее она молча возвращала пустую строку для null.
Расширенные примеры использования
$searchPattern = "error['\"]log";
$filename = "app.log";
$command = "grep " . escapeshellarg($searchPattern) . " " . escapeshellarg($filename);
echo $command;grep 'error['\''"\]log' 'app.log'
$params = ["first value", "second'value", "third"];
$safeParams = array_map('escapeshellarg', $params);
$command = "./script.sh " . implode(' ', $safeParams);
echo $command;./script.sh 'first value' 'second'\''value' 'third'
$dir = "/home/user/My Documents";
$output = shell_exec('ls -la ' . escapeshellarg($dir));
echo $output; // Выведет список файлов в каталоге с пробелом в имени$exePath = "/usr/local/bin/converter";
$inputFile = "input;data.csv";
$outputFile = "output & result.json";
$cmd = escapeshellarg($exePath) . " -i " . escapeshellarg($inputFile) . " -o " . escapeshellarg($outputFile);
// Путь к программе также экранирован для универсальности
exec($cmd);