在PHP网站上,他们建议的唯一真实检查是使用is_uploaded_file()
或move_uploaded_file()
,here。当然,出于各种原因,您通常不希望用户上传任何类型的文件。
因此,我经常使用一些“严格”的mime类型检查。当然这是非常有缺陷的,因为mime类型通常是错误的,用户无法上传他们的文件。伪造和/或改变也很容易。除此之外,每个浏览器和操作系统都以不同的方式处理它们。
另一种方法是检查扩展名,当然比mime类型更容易改变。
如果您只想要图片,请使用getimagesize()
之类的内容。
其他类型的文件怎么样? PDF,Word文档或Excel文件?甚至是纯文本文件?
修改:如果您没有mime_content_type或Fileinfo而系统(“文件-bi $ uploadedfile”)为您提供了错误的文件类型,还有哪些其他选项在那里?
答案 0 :(得分:33)
查看mime_content_type或Fileinfo。这些是内置的PHP命令,用于通过查看文件的内容来确定文件的类型。另外还要检查上面两页的评论,还有一些其他好的建议。
我个人幸运地使用了基本上system("file -bi $uploadedfile")
的东西,但我不确定这是不是最好的方法。
答案 1 :(得分:14)
恕我直言,所有MIME类型的检查方法都没用。
假设您应该拥有MIME类型application/pdf
。标准方法试图找到看起来像PDF标题(%PDF-
或smth。之类的东西)并且它们将成功返回'好吧,好像这是一个PDF文件'。但实际上这并不意味着什么。您可以上传仅包含%PDF-1.4
的文件,它将通过MIME检查。
我的意思是如果文件具有预期的MIME类型 - 它将始终传递MIME类型检查,否则结果是未定义的。
答案 2 :(得分:2)
我假设您将拥有一个固定的文件类型白名单,您将接受。
对于每种类型,您将不得不使用不同的技术来验证它们是该格式的有效示例。
有两个相关的问题:
它看起来大致可能是正确的类型吗? (对于JPEG,您可以检查标题,正如您所提到的。对于许多基于Unix的格式,您可以检查“魔术cookie”。)
它实际上是该类型的有效示例(例如,对于任何类似XML的格式,您可以针对DTD进行验证。)
我认为,对于每种格式,您应该为每种格式提出单独的问题,因为与ZIP文件相比,PDF的答案会有很大差异。
答案 3 :(得分:2)
我使用了与PHP 5.2兼容的mime_content_type,因为我既不能使用Fileinfo
(它需要PHP 5.3),也不能使用system()
,我的提供者禁用了它。
例如,我检查文件是否是文本文件,所以:
if (strcmp(substr(mime_content_type($f),0,4),"text")==0) { ... }
您可以在我的“PHP目录和子目录监听器&文件查看器和下载器”中查看完整示例: http://www.galgani.it/software_repository/index.php
答案 4 :(得分:2)
if(isset($_FILES['uploaded'])) {
$temp = explode(".", $_FILES["uploaded"]["name"]);
$allowedExts = array("txt","htm","html","php","css","js","json","xml","swf","flv","pdf","psd","ai","eps","eps","ps","doc","rtf","ppt","odt","ods");
$extension = end($temp);
if( in_array($extension, $allowedExts)) {
//code....
} else {
echo "Error,not Documentum type...";
}
}
答案 5 :(得分:1)
以下是来自iZend的函数file_mime_type
:
function file_mime_type($file, $encoding=true) {
$mime=false;
if (function_exists('finfo_file')) {
$finfo = finfo_open(FILEINFO_MIME);
$mime = finfo_file($finfo, $file);
finfo_close($finfo);
}
else if (substr(PHP_OS, 0, 3) == 'WIN') {
$mime = mime_content_type($file);
}
else {
$file = escapeshellarg($file);
$cmd = "file -iL $file";
exec($cmd, $output, $r);
if ($r == 0) {
$mime = substr($output[0], strpos($output[0], ': ')+2);
}
}
if (!$mime) {
return false;
}
if ($encoding) {
return $mime;
}
return substr($mime, 0, strpos($mime, '; '));
}
答案 6 :(得分:0)
对于PHP> = 5.3.0,您可以使用php的killPromise
(finfo_file)函数来获取有关文件的文件信息。
对于PHP <5.3.0,您可以使用系统的finfo_file
命令来获取文件信息。
所以只需将其设置为一个函数,
file