【问题标题】:How to check an exectuable's path is correct in PHP?如何在 PHP 中检查可执行文件的路径是否正确?
【发布时间】:2010-06-08 03:59:12
【问题描述】:

我正在为我的应用程序编写一个设置/安装程序脚本,基本上只是一个不错的配置文件前端。配置变量之一是 mysql 的可执行路径。在用户输入后(例如:/path/to/mysql-5.0/bin/mysql 或只是 mysql,如果它在他们的系统路径中),我想验证它是否正确。我最初的反应是尝试使用"--version" 运行它,看看会发生什么。然而,我很快意识到这将导致我编写这行代码:

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

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

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

【问题讨论】:

    标签: php security shell


    【解决方案1】:

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

    首先,使用is_executable() 验证它是否是可执行文件。

    PHP 为此公开了两个函数:escapeshellarg()escapeshellcmd()

    escapeshellarg() 在字符串周围添加单引号并引用/转义任何现有的单引号,从而允许您将字符串直接传递给 shell 函数并将其视为单个安全参数。

    escapeshellcmd() 转义字符串中可能被用来欺骗 shell 命令执行任意命令的任何字符。

    这应该会限制风险。

    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;
    }
    

    【讨论】:

    • +1 就我个人而言,我什至不会提示用户,而是会沿着路径寻找 .exe 是的,我想他们可以重命名 mysql,但是如何现实是这样吗?在最坏的情况下,您可能会输出“对不起,我在路径 上找不到 mysql(.exe)。它安装了吗?也许你重命名了它?”
    【解决方案2】:

    您可以尝试一个简单的file_exists 调用来确定该位置是否存在某物,同时使用is_executable 来确认您可以运行它。

    【讨论】:

      【解决方案3】:

      你看过is_dir()is_link()is_file()is_readable()

      希望这些帮助。

      【讨论】:

      • 我很确定拥有 45k 声望点的人知道基本的 PHP 文件功能...
      • @Matchu 哈哈——我认为代表比其他任何东西都更能衡量你的业余时间。 :-p。 @Robert 谢谢,我已经看到了这些,但是当文件在系统路径中时它们没有帮助。
      【解决方案4】:

      system('which '.escapeshellarg($input)) 将为您提供可执行文件的绝对路径,无论它只是名称还是绝对路径。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-08
        • 1970-01-01
        • 2013-04-21
        • 2013-05-04
        • 1970-01-01
        相关资源
        最近更新 更多