【发布时间】:2012-08-29 00:35:42
【问题描述】:
我想检查上传的文件类型,请告诉我在哪里可靠,在什么情况下可以获得有关文件类型的更准确信息?在这个:
$_files['uploaded_file']['type']
或在此:
$imgType = getimagesize($_files['uploaded_file']['tmp_name']);
$imgType['mime'];
?
【问题讨论】:
标签: php
我想检查上传的文件类型,请告诉我在哪里可靠,在什么情况下可以获得有关文件类型的更准确信息?在这个:
$_files['uploaded_file']['type']
或在此:
$imgType = getimagesize($_files['uploaded_file']['tmp_name']);
$imgType['mime'];
?
【问题讨论】:
标签: php
$_FILES[...]['type']从不可靠,它是用户提供的任意值。 getimagesize、exif_imagetype 或 finfo 是检查您所拥有物品的首选方式。另见Security threats with uploads。
【讨论】:
实际上,您可能应该使用图片附带的元数据 ($_files['uploaded_file']['type']),但在上传之前可能会被篡改。
如果您只是追求尺寸,请使用它,因为它比使用getimagesize 实际测量图像要快。但是,如果您需要文件类型信息,最好检查文件“所说”之外的内容,因为通过幼稚的检查很容易潜入可执行文件。
【讨论】:
我相信 getimagesize
因为任何人都可以编辑上传的文件类型使用任何 HTTP/HTTPS 标头,例如在 firefox 中篡改数据插件
【讨论】:
$_FILES['uploaded_file']['type'] 是用户输入 - 它是客户端定义的任意字符串。因此,使用任何东西都是不安全的。
getimagesize() 是一种更安全的方法,但它并不能完全保护您。
您还需要:
getimagesize() 只查看与文件关联的元数据,不查看文件数据。可以将恶意代码隐藏在看起来像图像的东西中。重新采样图像后,请确保已从服务器中删除上传的文件。【讨论】:
永远不要相信$_FILES["image"]["type"]。它接受从浏览器发送的任何内容,因此对于图像类型不要相信它。所以请使用getimagesize(),或者如果您想更安全,请使用finfo_open
【讨论】:
使用getimagesize() 将为您提供更一致的mime 信息,因为它使用它的环境mime-type 文件定义(GD 模块mime 数据库)。
如果您只依赖$_FILES['uploaded_file']['type'],那么它将包含客户端计算机(即浏览器)上定义的 mime-type,或者浏览器甚至可能不会发送 mime-type。
一个非常愚蠢的例子是检查if($_FILES['uploaded_file']['type'] == 'image/jpeg'),当使用将发送'image/pjpeg' mime-type 的 IE6/7 时可能会失败
这两种方法的替代方法是使用mime_content_type(),但它已被弃用为 PECL 模块,因此从 PHP 5.3.0 开始,FileInfo 函数应该与任何文件类型更一致 - 尽管我没有测试过了。
有关 mime 类型的更多概述,请查看这篇 SO 文章:How do I find the mime-type of a file with php?
【讨论】: