php - 在 PHP 中使用参数向量调用程序
问题描述
PHP 中用于执行外部程序的函数将单个整体命令字符串作为其参数。稍微不关心转义参数字符串可能会导致命令注入。
PHP 7.4 中增加了参数向量功能proc_open
,对于普通使用来说过于复杂。那么,有没有更简单的方法来调用带有参数向量的外部程序?
解决方案
此方法仅限于在 POSIX 系统上运行的 PHP
诸如system
,之类的函数popen
,无论是在 PHP 还是 C 和 POSIX 的上下文中,都不意味着采用合成的命令字符串。所以设计这样一个函数的思考过程应该从一个常数值的命令字符串开始。
接下来,PHP 确实提供了像 C 一样设置单个环境变量的能力(尽管之后不会取消设置它们),并且这种能力在很大程度上不受与注入相关的攻击的影响。所以我们可以构建一个带有环境变量的命令,组装一个命令向量,然后调用exec
shell 内置命令。
这是完整的代码:
<?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;
}
推荐阅读
- r - prcomp.default(data, scale = FALSE, center = FALSE) 中的错误:无法将常量/零列重新缩放为单位方差
- c - 指针和 .txt 文件
- matrix - 如何对包含整数的列表列表中的每个元素应用算术运算?
- r - 在 R 中具有二项分布和空间自相关的 GAM
- speech-recognition - SpeechRecognition 无法识别正确的单词或字母
- python - DJANGO - 按类别小计和按项目总计
- angular - 从复杂 json 中的值中搜索键
- google-chrome - 在没有身份 API 的 Chrome 扩展程序中使用 Gmail API?
- azure-cosmosdb - 日期时间的 Azure Cosmos DB UDF 严重减慢查询速度
- python - 尝试修改全局变量时出现“名称错误:名称未定义”