我有一个问题。我有一个PHP脚本(PHP 5),它将URL参数$_GET['file']
保存到变量$file
。现在有办法检查此变量是否是有效的文件名(例如:hello.txt
而不是/../otherdir/secret.txt
)。因为没有检查$ file变量,黑客就可以使用/../
来访问我的父文件夹。
答案 0 :(得分:6)
您可以查看php的basename
函数,它将返回文件名,请参阅下面的示例:
$file = '../../abc.txt';
echo basename($file); //output: abc.txt
注意:basename
从路径字符串中获取文件名,而不管文件是否存在。 file_exists
函数可用于验证文件是否存在。
答案 1 :(得分:1)
POSIX“完全可移植的文件名”列出了以下内容:A-Z
a-z
0-9
.
_
-
使用此代码使用正则表达式针对POSIX规则验证文件名:
/
-正斜杠(如果您需要验证路径而不是文件名)\w
-相当于[0-9a-zA-Z_]
-
.
-点划线空间$filename = '../../test.jpg';
if (preg_match('/^[\/\w\-. ]+$/', $filename))
echo 'VALID FILENAME';
else
echo 'INVALID FILENAME';
如果要确保它没有路径(没有正斜杠),则将正则表达式更改为'/^[\w\-. ]+$/'
。
答案 2 :(得分:0)
为什么不查找您不想要的字符,而不是检查有效字符。此外,文件名限制为 255 个字符:
function valid_filename(string $filename)
{
if (strlen($filename) > 255) { // no mb_* since we check bytes
return false;
}
$invalidCharacters = '|\'\\?*&<";:>+[]=/';
if (false !== strpbrk($filename, $invalidCharacters)) {
return false;
}
return true;
}
valid_filename('hello'); // true
valid_filename('hello.php'); // true
valid_filename('foo:bar.php'); // false
valid_filename('foo/bar'); // false
根据您的需要/操作系统调整 $invalidCharacters
。
来源:https://www.cyberciti.biz/faq/linuxunix-rules-for-naming-file-and-directory-names/
答案 3 :(得分:-1)
那会有用吗? http://php.net/manual/en/function.file-exists.php 例如,在您的情况下,
if(file_exists(str_replace("../", "", $file))){
// valid
}
else{
// invalid
}
文件可以在子文件夹中,但不在父文件夹中。
但是,如果您只对文件名感兴趣,
if(file_exists(pathinfo($file, PATHINFO_BASENAME))){
// valid
}
else{
// invalid
}
应该有用。
答案 4 :(得分:-3)
我想结合kamal pal和Pancake_M0nster的答案来创造简单:
if(file_exists(basename($file))){
// valid
}
else{
// invalid
}