我正在构建一个php文件上传器,我遇到了一些安全问题。例如,我不想允许“.php”文件上传。据我所知,检查文件类型的唯一方法是使用$_FILES['file']['type']
,并且它的值取决于浏览器。
我检查了多个浏览器并发现在选择常规.php文件时,不同的浏览器会返回以下值:
firefox: application/x-download
chrome: text/plain
safari: text/plain
IE: text/plain
opera: application/octet-stream
我还尝试使用常规.txt文件进行相同的实验,并且所有浏览都返回text/plain
作为mime类型。
所以这就是问题所在,如果我想允许.txt文件上传我应该做些什么来阻止.php文件上传?
答案 0 :(得分:3)
不要依赖客户端发送的信息。即使是客户端发送的媒体类型也可以伪造。
如果您不想允许PHP文件,请不要允许文件扩展名为.php
的文件或将其更改为.txt
:
if (strtolower(strrchr($_FILES['file']['name'], '.')) == '.php') {
// has file extension .php
}
答案 1 :(得分:2)
使用以下功能:
function Mime($path)
{
$result = false;
if (is_file($path) === true)
{
if (function_exists('finfo_open') === true)
{
$finfo = finfo_open(FILEINFO_MIME_TYPE);
if (is_resource($finfo) === true)
{
$result = finfo_file($finfo, $path);
}
finfo_close($finfo);
}
else if (function_exists('mime_content_type') === true)
{
$result = preg_replace('~^(.+);.*$~', '$1', mime_content_type($path));
}
else if (function_exists('exif_imagetype') === true)
{
$result = image_type_to_mime_type(exif_imagetype($path));
}
}
return $result;
}
这将返回任何文件的正确mime类型。
答案 2 :(得分:0)
尝试以下方法。这是FAR从傻瓜证明,但它是一个快速检查。它会阻止任何标记为.php的东西(因为它在客户端机器上),所以如果它们有类似'do_evil.php.txt'的东西,它将允许它BUT(阅读代码注释)
$file_ext = substr($_FILES['userfile']['name'], -3);
if($file_ext == 'php') {
//REJECT FILE
}
else {
// allow upload and once the file has been upload to the temp directory
// have a peice of code move the file to the final location and rename
// the file and specify a new file extension, using $file_ext as the extension
// so even if the file was 'do_evil.php.txt' when it comes to rest at the
// final location it will be 'do_evil.txt' and thus treated by the server as a
// text file and not PHP
}
我过去曾使用过上述结果。它绝不是防弹,但它至少应该有所帮助。我想我可能会有一些代码可以解决所有这些问题,如果你需要它就会去寻找它但没有承诺我能找到它