2010-06-08 41 views
0

我正在为我的应用程序编写安装程序/安装程序脚本,基本上只是配置文件的一个很好的前端。其中一个配置变量是mysql的可执行路径。用户键入后(例如:/path/to/mysql-5.0/bin/mysql或仅在mysql,如果它在他们的系统路径中),我想验证它是否正确。我最初的反应是尝试使用"--version"来运行它以查看返回的内容。然而,我很快意识到这会导致我写这行代码:如何在PHP中检查exectuable的路径是否正确?

shell_exec($somethingAUserHasEntered . " --version"); 

......这显然是一件非常糟糕的事情。现在,这是一个设置脚本,它只为可信用户设计,并且可能已经具有相对较高级别的系统访问权限,但我仍然认为上述解决方案不是我想写的内容。

有没有更好的方法来验证可执行文件路径?也许没有暴露出一个巨大的安全漏洞?

回答

2

运行任意用户命令就像运行基于用户输入的查询......转义是关键。

首先,验证它是否是使用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; 
} 
+0

+1我个人不会提示用户,但只会沿着路径寻找.exe是的,我想他们可以重新命名mysql,但这有多现实?在最糟糕的情况下,您可能会输出“对不起,我无法在路径上找到mysql(.exe)。是否已安装?可能是您重命名了它?” – Mawg 2010-06-08 05:22:34

1

你可以尝试一个简单的file_exists通话,以确定是否东西在该位置存在,与is_executable一起,以确认它的东西,你可以运行。

+0

当可执行文件位于PATH中时无法工作。 – nickf 2010-06-08 04:33:36

0

有你看着is_dir()is_link()is_file()is_readable()

希望这些帮助。

+1

我敢肯定用45K点名誉家伙知道基本的PHP文件的功能... – Matchu 2010-06-08 04:19:28

+0

@Matchu大声笑 - 我认为代表更多的是衡量你的业余时间比其他任何事情。 :-P。 @罗伯特谢谢,我已经看到了这些,但是当文件在系统PATH中时他们没有帮助。 – nickf 2010-06-08 04:35:14

0

system('which '.escapeshellarg($input))会给你的绝对路径到可执行文件,如果不管它只是名称或绝对路径。

相关问题