处理上传的文件时$_FILES['foo']['type']
完全不可靠。我发现如果你在OS X上更改了扩展名'键入'自动更改。
而是考虑:
$fileInfo = new \finfo(FILEINFO_MIME);
$mimeType = $fileInfo->buffer(file_get_contents($_FILES['foo']['tmp_name']));
$mimeType = explode(';', $mimeType);
现在,如果我将PHP脚本重命名为.jpg并上传它(在OS X 10.10上)$_FILES['foo']['type']
= image/jpeg
和$mimeType
= text/x-php
。
文件类型可以轻松更改,但PHP的finfo :: buffer如何被欺骗? PHP检查$_FILES['foo']['type']
和finfo(FILEINFO_MIME)
的内容有什么区别?
答案 0 :(得分:3)
PHP不检查$_FILES
类型中的任何内容;上传文件时,发送浏览器正在发送它认为文件类型的元数据。 $_FILES['file']['type']
只是反映了浏览器上传的此值。显然,任何人都可以随意欺骗。
Finfo使用magic database,它只是识别文件类型特征的集合。即,所有JPEG文件都有一个特征标题,所有ZIP文件都以某种方式启动,这种文件类型具有这些前导字节数,该文件类型具有这些类型的尾随字节等。如果你真的这么做很难欺骗想要生成某种类型的有效文件,但绝不是不可能的。
答案 1 :(得分:2)
$_FILES
从包含该文件的mime部分的Content-Type标头中获取它的类型。该部分是由发送文件的任何内容创建的,通常是一个根据文件扩展名猜测类型的浏览器。
另一方面,fileinfo扩展依赖于magic_open库。如果我没记错的话,magic_open将检查文件的多个属性,包括文件头以确定mimetype。尝试在一个html文件中嵌入php。我相信,由于文件标头为<!DOCTYPE html>
,因此会确定text/html
是mime类型。