【问题标题】:How can limit the access to a directory and its subdirectories in PHP?如何在 PHP 中限制对目录及其子目录的访问?
【发布时间】:2011-08-06 09:59:41
【问题描述】:

您好,我正在 PHP 上制作某种文件资源管理器,例如,如果我有这样的根文件夹:

/ (root)
|
|
|---home
      |
      |
      |---user
           |
           |
           |---folder
           |
           |---folder1
           |
           |---file1

现在我该怎么做user 只能浏览 /home/user/ 内的文件,而不能像 cd ../../ 那样去外面?非常感谢 :) 这是我用于cdcommand 的代码:

<?php
function cd($actualdir, $dir) {
    //echo $actualdir.$dir."<br>";
    if($dir == "..") {
        $expdir = explode("/", $actualdir);
        $newdir = array_pop($expdir);
        $fulldir = "";
        foreach($expdir as $value) {
            $fulldir .= $value."/";
        }
        $fulldir = substr($fulldir, 0, -1);
        if($fulldir == "./rootfs/home") {
            return "permission denied";
        } else {
            return $fulldir;

        }

    } else {
        if(file_exists($actualdir."/".$dir)) {
            //echo $dir;
            return $actualdir."/".$dir;
        } else {
            return "no";
        }
    }

}

?>

顺便说一句,根目录只是 Web 服务器根目录上的一个目录,它应该充当 shell 的系统根目录

编辑:基本上,如果用户是user,则只允许他进入/home/user 及其子目录。如果用户是testonly 到/home/test 和子目录。就是这样

【问题讨论】:

    标签: php file-permissions


    【解决方案1】:

    您可以使用 realpath($fulldir) 让文件系统解析相对路径(如 .. 和符号链接)。

    $fulldir = $actualdir . "/" . $dir;
    $rootdir = "/home/user";
    $length = strlen($rootdir);
    
    $realdir = realpath($fulldir);
    if ($realdir === false)
      return "file does not exist";
    
    if(substr($realdir, 0, $length) != $rootdir)
      return "permission denied";
    
    return "OK: $realdir";
    

    【讨论】:

    • 这行得通,因为它会停止cd ..,但不会停止cd ../../或类似的:(这也会杀死cd ..on allowed dirs
    • 您是否在现有文件夹结构上尝试过?我为此添加了一个检查以确保。
    【解决方案2】:

    终于结束了:

    if(strpos($dir, "../../") !== false) {
            return $dir." not allowed";
        }
        if($dir == "..") {
            $expdir = explode("/", $actualdir);
            $newdir = array_pop($expdir);
            $fulldir = "";
            foreach($expdir as $value) {
                $fulldir .= $value."/";
            }
            $userlength = strlen($user);
            $finalength = strlen($user)+14;
            $userdir = substr($actualdir."/".$dir, 0, $finalength);
    
            $fulldir = substr($fulldir, 0, -1);
            if (strpos($fulldir, $userdir) !== false) {
                return $fulldir;
    
            } else {
                return "permission denied";
            }
    

    【讨论】:

    • 哦,如果我输入 ../.. 会发生什么?还是...(赢)?或./..?
    【解决方案3】:

    最简单的解决方案?不要让用户实际上浏览您的文件系统。如果是文档上传应用或类似应用,请在数据库中表示它。

    因此,您将在数据库中表示目录(类别),以及每个类别的文件(项目)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-20
      • 2020-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-15
      • 1970-01-01
      • 2011-04-17
      相关资源
      最近更新 更多