PHP的finfo::buffer如何被欺骗?

4

在处理上传文件时,$_FILES['foo']['type']并不总是可靠的。我发现,如果在OS X上更改扩展名,'type'会自动更改。

相反地,可以考虑:

$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呢?$_FILES['foo']['type']finfo(FILEINFO_MIME)之间有什么区别?

2个回答

4

PHP不会检查$_FILES类型中的任何内容;上传文件时,发送文件的浏览器会发送其认为该文件类型的元数据。$_FILES['file']['type']只是反映了浏览器上传的这个值。很明显,任何人都可以自由地欺骗这个值。

Finfo使用magic数据库,这只是一组文件类型的特定标识特征。例如,所有JPEG文件都有一个特定的头部,所有ZIP文件都以某种方式开头,此文件类型具有这些前导字节数,那个文件类型具有那些末尾字节等等。如果您真的想生成特定类型的有效文件,则这更难欺骗,但并非不可能。


3
$_FILES 从包含文件的 MIME 部分的 Content-Type 标头获取其类型。这个部分是由发送文件的程序创建的,通常是一个浏览器,它会根据文件扩展名猜测文件类型。
另一方面,文件信息扩展依赖于 magic_open 库。如果我没记错的话,magic_open 将检查文件的多个属性,包括文件头,以确定 MIME 类型。尝试在 HTML 文件中嵌入 PHP。我相信,因为文件头是 <!DOCTYPE html>,所以会确定 text/html 是 MIME 类型。

感谢您的成功欺骗,您需要允许上传文本/HTML文件,并允许在允许运行PHP文件的文件夹中执行该文件吗?例如,如果您只允许图像,那么使用finfo无法将PHP代码插入其中吗? - texelate

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接