使用用户插入变量的最佳方法来清理exec命令

17

我正在编写一个网页界面,连接着我们公司使用的一款可怕的专有软件。这个软件没有真正的用户界面,需要我们授权客户端访问我们的系统才能获取数据。我的网页界面必须运行exec();函数,并且必须传递一些用户输入的变量。

$command = "report-call '$type' '$study' '$server' '$tag' '$specopt1' '$specopt2' '$specopt3' '$specopt4'";
$last_line = exec($command, $output, $returnvalue); 

现在我假设可以从变量$command中删除任何分号来保证安全,但是我不确定,这就是为什么我在下个月上线之前在这里提出的原因。

最好的方法是如何对$command进行净化? 我需要在变量中有一些特殊字符[ ] < > ! # $

1个回答

25

使用 PHP 专门用于此目的的函数:

$cmd = 
     "/usr/bin/do-something " . 
     escapeshellarg($arg1) . 
     ' ' . 
     escapeshellarg($arg2);

你也可以使用 escapeshellcmd()

这两者有什么不同?

escapeshellarg() 只在字符串周围添加 ',并在任何其他 ' 字符前添加 \。

http://www.php.net/escapeshellarg

escapeshellcmd() 转义所有受 shell 影响的字符($、\ 等),但不添加引号。

http://www.php.net/manual/en/function.escapeshellcmd.php

需要注意的是,如果您将 escapeshellarg() 用作带引号参数的一部分,则它将变得无用(实际上会添加引号)。

通常情况下,我们更喜欢使用 escapeshellcmd() 并添加我们自己的引号。

$cmd = 
    "/usr/bin/do-something '" . 
    escapeshellcmd($arg1) . 
    "' '" . 
    escapeshellcmd($arg2) . 
    "'";

注意安全!


5
删除了我的回答,因为显然我们同时在打字,但你给出了不错的例子。手册链接:http://us.php.net/manual/en/function.escapeshellarg.php,http://us.php.net/manual/en/function.escapeshellcmd.php - anonymous coward
3
请注意,escapeshellcmd()实际上并没有转义'!',因此如果您在例如Bash中运行命令,则仍然容易受到命令替换的攻击(例如“this-is-a-test-!467”,其中“!467”将被您Shell历史记录中编号为467的任何内容所替换)。 escapeshellarg()可以缓解这种情况。 - madsen
这非常有帮助,我以前从未听说过这些命令。非常感谢。 - Andy Borgmann

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接