Invoke a program using argument vector in PHP
one text
Solution:
This method is limited to PHP running on POSIX systems
The functions such as system
, popen
, whether in the context of PHP or C & POSIX, are never meant to take synthesized command strings. So the thinking process of designing such a function should begin with a constant-valued command string.
Next, PHP does provide the capability to set individual environment variables like C (though not unsetting them afterwards), and this capability is largely immune to injection-related attacks. So we can build a command that takes environment variables, assemble a command vector, then invoke exec
shell built-in command.
Here's the full code:
<?php
$spawncmd = <<<'EOF'
set --
n=0
while [ $n -lt $execargc ] ; do
eval "set -- \"\$@\" \"\$execarg$n\""
unset -v execarg$n
n=$((n+1))
done
unset -v execargc
exec "$@"
EOF;
// Invokes external program and return its output.
function spawn($args)
{
global $spawncmd;
putenv("execargc=".count($args));
for($i=0; $i<count($args); $i++)
putenv("execarg$i=".$args[$i]);
$ret = shell_exec($spawncmd);
putenv("execargc=");
for($i=0; $i<count($args); $i++)
putenv("execarg$i=");
return $ret;
}
// Invokes external program and return its exit status.
function catspawn($args)
{
global $spawncmd;
putenv("execargc=".count($args));
for($i=0; $i<count($args); $i++)
putenv("execarg$i=".$args[$i]);
$ret = null;
passthru($spawncmd, $ret);
putenv("execargc=");
for($i=0; $i<count($args); $i++)
putenv("execarg$i=");
return $ret;
}
// Argument vector version of popen.
function pspawn($args, $mode)
{
global $spawncmd;
putenv("execargc=".count($args));
for($i=0; $i<count($args); $i++)
putenv("execarg$i=".$args[$i]);
$ret = popen($spawncmd, $mode);
putenv("execargc=");
for($i=0; $i<count($args); $i++)
putenv("execarg$i=");
return $ret;
}
Source