command line - php prevent '`rm -rf ~/`;'
Good day guys. The issue I am having is specifically with handling this specific input case.
A part of my project I need to do is to take argument though command line into a PHP script. for eg ./do_op_2.php "`rm -rf ~/`;" .
I have tried using escapeshellarg($argv[1]), escapesellcmd($argv[1]); but to no avail it still executes the command. I have tried iterating through the string looking for ` and ; before anything happens, it is still executed.
If there are any more specific questions please do ask, I am willing to give more information.
Code for those who are curious.
#!/usr/bin/php
<?php
unset($argv[0]);
$argv[1] = escapeshellarg($argv[1]);
$argv[1] = escapeshellcmd($argv[1]);
function add($a, $b)
{
if (is_numeric($a) && is_numeric($b))
return ($a + $b);
else
return (0);
}
function minus($a, $b)
{
if (is_numeric($a) && is_numeric($b))
return ($a - $b);
else
return (0);
}
function mult($a, $b)
{
if (is_numeric($a) && is_numeric($b))
return ($a * $b);
else
return (0);
}
function divide($a, $b)
{
if (is_numeric($a) && is_numeric($b))
return ($a / $b);
else
return (0);
}
function mod($a, $b)
{
if (is_numeric($a) && is_numeric($b))
return ($a % $b);
else
return (0);
}
function ft_split($str)
{
$ret = array_filter(preg_split('/\s+/', $str));
return ($ret);
}
if ($argc == 2)
{
$split = ft_split(trim($argv[1], " \t"));
if (is_numeric($split[0]) && is_numeric($split[2]))
{
if ($split[1] == "+")
echo add(trim($split[0], " \t"), trim($split[2], " \t")) . "\n";
else if ($split[1] == "-")
echo minus(trim($split[0], " \t"), trim($split[2], " \t")) . "\n";
else if ($split[1] == "*")
echo mult(trim($argv[0], " \t"), trim($split[2], " \t")) . "\n";
else if ($split[1] == "/")
echo divide(trim($split[0], " \t"), trim($split[2], " \t")) . "\n";
else if ($split[1] == "%")
echo mod(trim($split[0], " \t"), trim($split[2], " \t")) . "\n";
else
echo "Syntax Error\n";
}
else
echo "Syntax Error\n";
}else
echo "Incorrect Parameters\n";
?>
Answer
Solution:
The only thing I can think of is command substitution (see also parameter substitution) - something which happens in bash and other shells. If this is what's going on, then your reporting of the situation is a little misleading (read on).
It's very unlikely that PHP will be doing this, it'll be done by the shell, and there is no way to modify your code to prevent this... It's a feature of the shell.
For example a variable, using
${...}
:It's also possible to run a command and use the output (stdout) as the value with
$(...)
:Another variant of this is using backticks:
You've listed the following in your question:
The use of single quotes (
'
) should prevent the shell from substituting the backticks:But using double quotes (
"
) will not prevent this:I can only presume that you've reported single quotes, but actually used double quotes when you observed this behaviour. Your comment supports this theory.