灰儿 发表于 2021-11-28 07:52:43

Veno-File-Manager (VFM3)云盘游客可查看所有文件漏洞解决思路

Veno-File-Manager (VFM3)云盘游客可查看所有文件漏洞解决思路

如果游客开启了“查看文件”权限,游客打开云盘时,不仅能看到主文件夹里的文件,通过在URL地址栏中手工添加“?dir=uploads/子文件夹名称”参数也可以看到子文件夹里文件。



解决思路(把未登录用户设置为“guest”用户,并设置可防问的目录权限):

1.修改未登录用户访问目录权限。
打开 主目录/vfm-admin/class/class.gatekeeper.php文件中的 getUserInfo($info) 函数,添加未登录用户可访问的目录名。修改后代码如下:      /**
         * Get user info ('name', 'role', 'dir', 'email')   获取用户信息(“名称”、“角色”、“目录”、“电子邮件”)
         *
         * @param int $info index of corresponding user info
         *
         * @return info requested
         */
      public static function getUserInfo($info)
      {
            if (GateKeeper::isUserLoggedIn()
                && isset($_SESSION['vfm_user_name'])
                && strlen($_SESSION['vfm_user_name']) > 0
            ) {
                $username = $_SESSION['vfm_user_name'];
                $curruser = Utils::getCurrentUser($username);

                if (isset($curruser[$info]) && strlen($curruser[$info]) > 0) {
                  return $curruser[$info];
                }
            } else if(!GateKeeper::isUserLoggedIn() && SetUp::getConfig('viewdirs_enable_guest') ){      
                              if( !SetUp::getConfig('view_enable_guest')){
                                       return null;}
               $guestpatharray = array ('dir' => '["guest","公共目录"]',);    //游客目录
                           $userpatharray = json_decode($guestpatharray['dir'], true);         
                           return $guestpatharray['dir'];
            }
            return null;
      }2.修改未登录用户,显示用户名为“guest”(非必须)。
查找 主目录/vfm-admin/class/class.utils.php文件中的 getUserName()函数,大约在231行,代码如下:
      /**
         * Return current username返回当前用户名
         *
         * @return username
         */
      public static function getUserName()
      {
            return isset($_SESSION['vfm_user_name']) ? $_SESSION['vfm_user_name'] : '--';
      }修改为:
      /**
         * Return current username返回当前用户名
         *
         * @return username
         */
      public static function getUserName()
      {
            return isset($_SESSION['vfm_user_name']) ? $_SESSION['vfm_user_name'] : 'guest';
      }
与解决此漏洞相关文件:
主目录/vfm-admin/class/class.gatekeeper.php   //验证当前用户权限的类
主目录/vfm-admin/class/class.location.php   //与路径和目录相关的类
主目录/vfm-admin/include/head.php   //头部,重要的内容
主目录/vfm-admin/include/navbar.php   //顶部标题
主目录/vfm-admin/class/class.dir.php
主目录/vfm-admin/include/breadcrumbs.php   //路径显示
主目录/vfm-admin/include/list-folders.php   //文件夹列表
主目录/vfm-admin/include/list-files.php   //文件列表
主目录//vfm-admin/include/load-js.php


主目录/vfm-admin/admin-panel/view/admin-head.php    //加载 admin-head-settings.php文件

主目录/vfm-admin/class/class.gatekeeper.php    //与用户权限相关的类
isAllowed($action)   //检查是否允许目标操作函数-
变量$role为角色,分别为普通用户(user)、管理员(admin)角色),如果$role内容为空就设置为游客(guest)角色。
      /**
         * Check if target action is allowed检查是否允许目标操作
         *
         * @param string $action action to check
         *
         * @return true/false
         */
      public static function isAllowed($action)
      {
            if ($action && GateKeeper::isAccessAllowed()) {
                $role = GateKeeper::getUserInfo('role');
                $role = $role == null ? 'guest' : $role;

                if ($role == 'superadmin') {
                  return true;
                }

                $base_actions = array(
                  'view_enable',
                  'viewdirs_enable',
                  'download_enable',
                );

                // Base actions true for all except Guest and User 基本操作适用于除来宾和用户之外的所有用户
                if (in_array($action, $base_actions) && $role !== 'guest' && $role !== 'user') {
                  return true;
                }

                $role_ext = $role == 'admin' ? '' : '_'.$role;

                return SetUp::getConfig($action.$role_ext);
            }
            return false;
      }$gateKeeper->isUserLoggedIn()//检查用户是否已登录
/**
         * Check if user is logged in检查用户是否已登录
         *
         * @return true/false
         */
      public static function isUserLoggedIn()
      {
            if (isset($_SESSION['vfm_user_name'])
                && isset($_SESSION['vfm_logged_in'])
                && $_SESSION['vfm_logged_in'] == 1
            ) {
                return true;
            }
            return false;
      }$gateKeeper->isSuperAdmin()   //检查用户是否为超级管理员
      /**
         * Check if user is SuperAdmin   检查用户是否为超级管理员
         *
         * @return true/false
         */
      public static function isSuperAdmin()
      {
            if (GateKeeper::getUserInfo('role') === 'superadmin') {
                return true;
            }
            return false;
      }getUserInfo($info)   获取用户信息(“名称”、“角色”、“目录”、“电子邮件”)
      /**
         * Get user info ('name', 'role', 'dir', 'email')   获取用户信息(“名称”、“角色”、“目录”、“电子邮件”)
         *
         * @param int $info index of corresponding user info
         *
         * @return info requested
         */
      public static function getUserInfo($info)
      {
            if (GateKeeper::isUserLoggedIn()
                && isset($_SESSION['vfm_user_name'])
                && strlen($_SESSION['vfm_user_name']) > 0
            ) {
                $username = $_SESSION['vfm_user_name'];
                $curruser = Utils::getCurrentUser($username);

                if (isset($curruser[$info]) && strlen($curruser[$info]) > 0) {
                  return $curruser[$info];
                }
            }
            return null;
      } isAccessAllowed()检查用户是否可以访问
      /**
         * Check if user can access   检查用户是否可以访问
         *
         * @return true/false
         */
      public static function isAccessAllowed()
      {
            if (!GateKeeper::isLoginRequired() || GateKeeper::isUserLoggedIn()) {
                return true;
            }
            return false;
      } isLoginRequired()检查是否开启游客“您需要登录才可以查看”
      /**
         * Check if login is required to view lists检查查看列表是否需要登录
         *
         * @return true/false
         */
      public static function isLoginRequired()
      {
            if (SetUp::getConfig('require_login') == false) {
                return false;
            }
            return true;
      }
主目录/vfm-admin/class/class.location.php   //用户目录和文件路径
checkUserDir()       //检查目录是否可供用户使用
      /**
         * Check if directory is available for user   检查目录是否可供用户使用
         *
         * @param string $relative relative path to index.php
         *
         * @return true/false
         */
      public function checkUserDir($relative = false)
      {
            $thispath = $this->getDir(true, false, false, 0, $relative);

            if (!is_dir(realpath($thispath))) {
                return false;
            }

            $getUserInfo = GateKeeper::getUserInfo('dir');
            if ($getUserInfo === null) {
                return true;
            }

            $startdir = SetUp::getConfig('starting_dir');
            $userpatharray = $getUserInfo !== null ? json_decode($getUserInfo, true) : array();
            $thiscleanpath = ltrim($thispath, './');
            $cleanstartdir = rtrim(ltrim($startdir, './'), '/');
            $thispatharray = explode('/', $thiscleanpath);
            $checkpath = $thispatharray === $cleanstartdir && strlen($cleanstartdir) ? $thispatharray : $thispatharray;
            $pathcounter = $thispatharray === $cleanstartdir && strlen($cleanstartdir) ? (int)2 : (int)1;

            // Check for multiple folders assigned   检查是否分配了多个文件夹
            foreach ($userpatharray as $value) {

                // Check if a sub/sub folder is assigned
                $userdirarray = explode('/', $value);
                $usersubs = count($userdirarray) - 1;
                if ($usersubs > 0) {
                  $subscounter = $usersubs + $pathcounter;
                  for ($i = $pathcounter; $i < $subscounter; $i++) {
                        $checkpath .= '/'.$thispatharray[$i];
                  }
                }

                // Finally check if the location is accessible by the user
                if ($value === $checkpath) {
                  return true;
                }
            }
            return false;
      }makeLink()      创建注销、删除和打开目录的链接(用户登录?logout)/**
   * Create links to logout, delete and open directory创建注销、删除和打开目录的链接
   *
   * @param boolean $logout set logout
   * @param string$delete path to delete
   * @param string$dir    path to link
   *
   * @return link
   */
public function makeLink($logout, $delete, $dir)
{
$link = '?';

if ($logout == true) {
    $link .= 'logout';
    return $link;
}
$link .= 'dir='.$dir;
if ($delete != null) {
    $link .= '&del='.base64_encode($delete);
}
return $link;
}
主目录/vfm-admin/class/class.utils.php//常用工具类
Utils::getCurrentUser($username)按用户名获取用户数据
      /**
         * Get user data by username按用户名获取用户数据
         *
         * @param int $search username to search
         *
         * @return user array requested
         */
      public static function getCurrentUser($search)
      {
            $currentuser = array();
            $users = SetUp::getUsers();
            if ($users) {
                foreach ($users as $user) {
                  if (strtolower($user['name']) == strtolower($search)) {
                        $currentuser = $user;
                        return $currentuser;
                  }
                }
            }
            return false;
      }主目录/vfm-admin/class/class.setup.php//设置类
SetUp::getUsers()获取所有用户数据
      /**
         * Get all users from users.php   从users.php   获取所有用户
         *
         * @return users array
         */
      public static function getUsers()
      {
            global $_USERS;
            if (isset($_USERS)) {
                return $_USERS;
            }
            return false;
      }主目录/vfm-admin/class/class.location.php文件中的 checkUserDir()函数
$userpatharray = $getUserInfo !== null ? json_decode($getUserInfo, true) :array();


后台管理面板与游客设置相关的文件config.php配置文件中与游客相关函数:
'starting_dir' => './uploads/',            主目录(上传文件存放文件夹)
'require_login' => false,                      您需要登录才可以查看    => 关闭
'view_enable_guest' => true,               查看文件_开启_游客=> 开启
'download_enable_guest' => true,      打包下载_开启_游客=> 开启
'viewdirs_enable_guest' => false,      查看文件夹_开启_游客   => 关闭
'sendfiles_enable_guest' => true,       分享文件_开启_游客   => 开启

主目录/vfm-admin/admin-panel/view/admin-head-settings.php   //保存与游客用户权限相关的设置参数
    // Users permissions
    // Guest
    $_CONFIG['view_enable_guest'] = (isset($_POST['view_enable_guest']) ? true : false);
    $_CONFIG['download_enable_guest'] = (isset($_POST['download_enable_guest']) ? true : false);
    $_CONFIG['sendfiles_enable_guest'] = (isset($_POST['sendfiles_enable_guest']) ? true : false);
    $_CONFIG['viewdirs_enable_guest'] = (isset($_POST['viewdirs_enable_guest']) ? true : false);

主目录/vfm-admin/admin-panel/view/dashboard/permissions.php   //管理后台用户权限设置
定义与游客相关的变量:

$rolename = $setUp->getString("role_guest");
$rolekey = '_guest';


灰儿 发表于 2021-12-3 16:38:09

主目录/vfm-admin/admin-panel/view/dashboard/permissions.php   //管理后台用户权限设置
定义与游客相关的变量:

$rolename = $setUp->getString("role_guest");
$rolekey = '_guest';

游客权限设置源代码:
<h4><?php echo $rolename; ?></h4>
<div class="row toggle-reverse-next">
    <div class="col-sm-6">
      <div class="form-group bg-warning py-2">
            <div class="checkbox checkbox-bigger clear">
<label>
    <input type="checkbox" name="require_login"
    <?php
    if ($setUp->getConfig('require_login')) {
      echo "checked";
    } ?>>
    <i class="fa fa-lock fa-fw"></i>
    <?php print $setUp->getString("require_login"); ?>
</label>
            </div>
      </div>
    </div>
</div>
<div class="reverse-toggle-target">
    <div class="row">
      <div class="col-sm-6">
            <div class="toggle">
<div class="checkbox checkbox-big toggle">
    <label>
      <input type="checkbox" name="view_enable<?php echo $rolekey; ?>"
      <?php
      if ($setUp->getConfig('view_enable'.$rolekey)) {
            echo "checked";
      } ?>>
            <span class="fa-stack">
            <i class="fa fa-file-o fa-stack-2x"></i>
            <i class="fa fa-eye fa-stack-1x"></i>
            </span>
      <?php print $setUp->getString("view_files"); ?>
    </label>
</div>
            </div>
            <div class="toggleme">
<div class="checkbox checkbox-big toggle">
    <label>
      <input type="checkbox" name="download_enable<?php echo $rolekey; ?>"
      <?php
      if ($setUp->getConfig('download_enable'.$rolekey)) {
            echo "checked";
      } ?>>
            <span class="fa-stack">
            <i class="fa fa-file-o fa-stack-2x"></i>
            <i class="fa fa-download fa-stack-1x"></i>
            </span>
      <?php print $setUp->getString("download_files"); ?>
    </label>
</div>

<div class="checkbox checkbox-big">
    <label>
      <input type="checkbox" name="sendfiles_enable<?php echo $rolekey; ?>"
      <?php
      if ($setUp->getConfig('sendfiles_enable'.$rolekey)) {
            echo "checked";
      } ?>>
            <span class="fa-stack">
            <i class="fa fa-file-o fa-stack-2x"></i>
            <i class="fa fa-paper-plane-o fa-stack-1x"></i>
            </span>
      <?php print $setUp->getString("share_files"); ?>
    </label>
</div>
            </div>
      </div>

      <div class="col-sm-6">
            <div class="checkbox">
<label>
    <input type="checkbox" name="viewdirs_enable<?php echo $rolekey; ?>"
    <?php
    if ($setUp->getConfig('viewdirs_enable'.$rolekey)) {
      echo "checked";
    } ?>>
      <span class="fa-stack">
          <i class="fa fa-folder fa-stack-2x"></i>
          <i class="fa fa-eye fa-stack-1x fa-inverse"></i>
      </span>
    <?php print $setUp->getString("view_folders"); ?>
</label>
            </div>
      </div>
    </div>
</div>

游客权限设置转换为html内容如下:
//标题
<h4>游客</h4>
//您需要登录才可以查看
<div class="row toggle-reverse-next">
                  <div class="col-sm-6">
                        <div class="form-group bg-warning py-2">
                            <div class="checkbox checkbox-bigger clear">
                              <label>
                                    <input type="checkbox" name="require_login">
                                    <i class="fa fa-lock fa-fw"></i>
                                    您需要登录才可以查看                              </label>
                            </div>
                        </div>
                  </div>
                </div>


//具体权限选项
<div class="reverse-toggle-target">
                  <div class="row">
                        <div class="col-sm-6">
                            <div class="toggle">
                              <div class="checkbox checkbox-big toggle">
                                    <label>
                                        <input type="checkbox" name="view_enable_guest" checked="">
                                          <span class="fa-stack">
                                              <i class="fa fa-file-o fa-stack-2x"></i>
                                              <i class="fa fa-eye fa-stack-1x"></i>
                                          </span>
                                        查看文件                                    </label>
                              </div>
                            </div>
                            <div class="toggleme">
                              <div class="checkbox checkbox-big toggle">
                                    <label>
                                        <input type="checkbox" name="download_enable_guest" checked="">
                                          <span class="fa-stack">
                                              <i class="fa fa-file-o fa-stack-2x"></i>
                                              <i class="fa fa-download fa-stack-1x"></i>
                                          </span>
                                        打包下载                                    </label>
                              </div>

                              <div class="checkbox checkbox-big">
                                    <label>
                                        <input type="checkbox" name="sendfiles_enable_guest" checked="">
                                          <span class="fa-stack">
                                              <i class="fa fa-file-o fa-stack-2x"></i>
                                              <i class="fa fa-paper-plane-o fa-stack-1x"></i>
                                          </span>
                                        分享                                    </label>
                              </div>
                            </div>
                        </div>

                        <div class="col-sm-6">
                            <div class="checkbox">
                              <label>
                                    <input type="checkbox" name="viewdirs_enable_guest" checked="">
                                        <span class="fa-stack">
                                          <i class="fa fa-folder fa-stack-2x"></i>
                                          <i class="fa fa-eye fa-stack-1x fa-inverse"></i>
                                        </span>
                                    查看文件夹                              </label>
                            </div>
                        </div>
                  </div>
                </div>
页: [1]
查看完整版本: Veno-File-Manager (VFM3)云盘游客可查看所有文件漏洞解决思路