我正在为我的应用程序编写一个设置/安装程序脚本,基本上只是配置文件的一个很好的前端。其中一个配置变量是mysql的可执行路径。在用户键入它之后(例如:/path/to/mysql-5.0/bin/mysql
,或者如果它在他们的系统路径中,则只输入mysql
),我想验证它是否正确。我最初的反应是尝试用"--version"
运行它,看看会有什么结果。然而,我很快意识到这会导致我写这行代码:
shell_exec($somethingAUserHasEntered . " --version");
...which显然是一件非常糟糕的事情。现在,这是一个仅为可信用户设计的设置脚本,这些用户可能已经对系统具有相对较高的访问权限,但我仍然不认为上面的解决方案是我想要编写的。
有没有更好的方法来验证可执行文件路径?也许它不会暴露出一个巨大的安全漏洞?
发布于 2010-06-08 12:26:49
运行任意用户命令就像根据用户输入运行查询一样……逃脱是关键。
首先,使用is_executable()
验证它是否是可执行文件。
PHP为此公开了两个函数:escapeshellarg()
和escapeshellcmd()
。
escapeshellarg()
在字符串两边添加单引号,并对任何现有的单引号进行引号/转义,允许您将字符串直接传递给shell函数,并将其视为单个安全参数。
escapeshellcmd()
转义字符串中可能用于诱使外壳命令执行任意命令的任何字符。
这应该会限制风险的数量。
if(is_executable($somethingAUserHasEntered)) {
shell_exec(escapeshellarg($somethingAUserHasEntered) . " --version");
}
毕竟,做rm --version
并不是很有害,而且"rm -rf / &&" --version
会让你很快到达任何地方。
编辑:既然你提到了PATH
...下面是一个快速函数,用于根据PATH
规则验证文件是否为可执行文件:
function is_exec($file) {
if(is_executable($file)) return true;
if(realpath($file) == $file) return false; // Absolute Path
$paths = explode(PATH_SEPARATOR, $_ENV['PATH']);
foreach($paths as $path) {
// Make sure it has a trailing slash
$path = rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
if(is_executable($path . $file)) return true;
}
return false;
}
发布于 2010-06-08 12:12:30
您可以尝试一个简单的file_exists
调用来确定在该位置是否存在某个,并使用一个is_executable
来确认它是可以运行的。
发布于 2010-06-08 12:16:15
您是否看过is_dir()
、is_link()
、is_file()
或is_readable()
希望这些能有所帮助。
https://stackoverflow.com/questions/2994679
复制相似问题