我正在编写一个 PHP 库,它需要访问系统并访问一个没有 PHP 接口(或 PHP 库)的命令行程序。因此,我想知道访问系统以从 CLI 程序中检索输出的最佳(也是最安全的方式)是什么?我已经查看了system()
和exec()
,但仍然不确定在这种情况下哪个最适合使用。
该库将获取一串用户传递的文本,并将其传输到命令行,取回另一串文本。显然,通过将用户提供的数据传递给 CLI,我将进行验证以确保不能传递任何可执行数据。
我正在编写一个 PHP 库,它需要访问系统并访问一个没有 PHP 接口(或 PHP 库)的命令行程序。因此,我想知道访问系统以从 CLI 程序中检索输出的最佳(也是最安全的方式)是什么?我已经查看了system()
和exec()
,但仍然不确定在这种情况下哪个最适合使用。
该库将获取一串用户传递的文本,并将其传输到命令行,取回另一串文本。显然,通过将用户提供的数据传递给 CLI,我将进行验证以确保不能传递任何可执行数据。
我建议与andshell_exec()
一起使用。escapeshellcmd()
escapeshellarg()
澄清一下(当我第一次发布这个答案时,我正在旅途中):保护shell 命令的正确方法是:
$exe = 'cat';
$args = array('/etc/passwd');
$args = array_map('escapeshellarg', $args);
$escaped = escapeshellcmd($exe . ' ' . implode(' ', $args));
当然,以上只是一个虚拟示例。但主要思想是应用escapeshellarg()
到每个参数,然后调用escapeshellcmd()
整个命令字符串(包括可执行文件的路径和先前转义的参数)。这在任意命令中至关重要。
注意:通过安全,我的意思是通过转义具有特殊含义的字符(如, ,等) (请参阅Wikipedia 链接),同时正确引用空格和其他可能也具有特殊含义的字符,从而无法执行shell 注入攻击由shell解释。>
<
&&
|
除此之外,如果您已经将所有允许的命令列入白名单,那么您已经拥有了最好的安全性,并且您不需要上述功能(尽管无论如何使用它们并没有什么坏处)。
关于实际的调用函数,它们几乎都做同样的事情,但有一些怪癖。就个人而言,我更喜欢它,shell_exec()
因为它的返回值更加通用(来自此页面):
Except from the system()
exit return code, you can mimic the behavior of all the other functions with the return value of shell_exec()
. However, the inverse it's either harder to do, or just not possible.
I hope this clears things up for you.
理想情况下,您将使用passthru()
预定义的可能输入列表(这样如果用户input == 'operation_a'
可以{ passthru('operation_a'); }
不用担心清理输入)。否则,使用passthru()
一些严重的输入卫生。passthru()
允许您捕获命令的输出并将整个块传回浏览器。如果您期望二进制输出(例如来自图像生成等),此功能特别有用。