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';
主目录/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]