Xeo*_*oss 5 php filesystems directory
我正在尝试创建一个阻止访问我的一些低级目录的函数.例如,在构建我的网站时,我不希望上传任何低于/ var/www/html/site/uploads /的内容,如果我在编码时犯了错误.这也有助于在删除缓存文件或其他任何内容时防止目录删除拼写错误.
这可以通过realpath()和strcasecmp()轻松完成.
问题是我不能使用realpath()来生成绝对路径,因为对具有不存在的目录的此函数的任何调用都将返回FALSE.以下是我查看验证它们的路径的最佳尝试.
function is_sub_dir($path = NULL, $parent_folder = NULL) {
//Convert both to real paths
//Fails if they both don't exist
//$path = realpath($path);
//$parent_folder = realpath($parent_folder);
//Neither path is valid
if( !$path OR !$parent_folder ) {
return FALSE;
}
//Standarize the paths
$path = str_replace('\\', '/', $path);
$parent_folder = str_replace('\\', '/', $parent_folder);
//Any evil parent directory requests?
if(strpos($path, '/..') !== FALSE) {
return FALSE;
}
//If the path is greater
if( strcasecmp($path, $parent_folder) > 0 ) {
return $path;
}
return FALSE;
}
//BAD FOLDER!!!
var_dump(is_sub_dir('/var/www/html/site/uploads/../', '/var/www/html/site/uploads/'));
Run Code Online (Sandbox Code Playgroud)
有谁知道如何正确放置文件路径块以防止低级文件夹访问?
:更新:
我想进一步解释这个检查方法将用于多个服务器以及创建高于给定目录的目录.
例如,在我的uploads目录中,我希望允许管理员创建新的子目录,例如... uploads/sub /.通过确定一个可靠的方法来确保给出的目录实际上高于父目录 - 我可以感觉更安全,允许我的管理员使用uploads文件夹中的文件系统.
因为我可能需要在创建它之前验证uploads/sub是否高于uploads /我不能使用realpath()因为uploads/sub不再存在.
至于PHP动态计算的uploads文件夹的实际位置.
define('UPLOAD_PATH', realpath(dirname(__FILE__)));
Run Code Online (Sandbox Code Playgroud)
:更新2:
我有一个想法,如果我使用realpath比较整个路径减去最后一个目录段,该怎么办?那么即使仍然需要创建最后一个目录段 - 可以强制路径的其余部分匹配最小父目录?
不是你当前问题的答案,但你绝不应该在真实的安全环境中使用黑名单.
那是因为您可能会更改目录布局但忘记更新黑名单,从而使您的安全无效.
使用白名单,您可以列出允许上传到的位置.如果您随后更改了布局并忘记更改白名单,则您的安全性实际上已增加,而不是减少.而用户抗议的嚎叫会提醒您忘记.
在禁止对下级目录的访问而言,我认为这是得到真正的路径的简单的事情(与所有这些./,并../与\\转化为规范化的形式),然后,如果它开始/var/www/html/site/uploads/,失败,如果有任何更/后面的字符那.
之前我已经完成了这个规范化,它基本上由(来自内存)组成:
\\与/(所以它使用UNIX-ISMS)./,那么在前面添加你的基目录(所以它总是一个绝对路径)././与/("在当前目录逗留"动作摆脱没用)./X/../与/其中X是任何非/字符(摆脱的下了目录移动).剩下的东西通常是安全的,虽然可能有边缘情况取决于是否有更多的目录移动命令可用(我已经看作...是等价的../..).你的旅费可能会改变.
即使路径中的最后一个目录尚不存在,以下代码也可以工作。任何犯规或额外丢失的目录都会返回 false。
此函数的限制是它仅适用于(大多数)已经存在的路径和使用标准英文字符的目录名称(/.hts/、/files.90.3r3/、/my_photos/)等..)
function is_sub_dir($path = NULL, $parent_folder = SITE_PATH) {
//Get directory path minus last folder
$dir = dirname($path);
$folder = substr($path, strlen($dir));
//Check the the base dir is valid
$dir = realpath($dir);
//Only allow valid filename characters
$folder = preg_replace('/[^a-z0-9\.\-_]/i', '', $folder);
//If this is a bad path or a bad end folder name
if( !$dir OR !$folder OR $folder === '.') {
return FALSE;
}
//Rebuild path
$path = $dir. DS. $folder;
//If this path is higher than the parent folder
if( strcasecmp($path, $parent_folder) > 0 ) {
return $path;
}
return FALSE;
}
Run Code Online (Sandbox Code Playgroud)