【发布时间】:2014-01-16 06:02:56
【问题描述】:
我想知道$_FILES["file"]["type"]和end(explode(".", $name)有什么区别,以及确定检索到的文件类型是否真的是文件的正确内容的适当方法。
例如,对名为“image.exe”并重命名为“image.jpg”的文件进行排序的最佳方法是什么。
我看过很多关于 MIME 类型的讨论,但似乎该方法已被弃用。
【问题讨论】:
标签: php file types upload explode
我想知道$_FILES["file"]["type"]和end(explode(".", $name)有什么区别,以及确定检索到的文件类型是否真的是文件的正确内容的适当方法。
例如,对名为“image.exe”并重命名为“image.jpg”的文件进行排序的最佳方法是什么。
我看过很多关于 MIME 类型的讨论,但似乎该方法已被弃用。
【问题讨论】:
标签: php file types upload explode
这是阅读扩展名的正确方法:
$ext = pathinfo($name, PATHINFO_EXTENSION);
检查某物是否为图像的正确方法是尝试使用图像工具读取它,例如imagemagick 或GD。 GD 更容易,但 imagemagick 更擅长处理大图像,例如从 12 兆像素相机上传的图像。
如果您担心 jpg 真的是 exe,安全处理它的唯一方法是将其读取为 jpg 并尝试创建新的 jpg(通常同时调整其大小)。 Gmail 会处理图片附件。
还要注意真正的 jpeg 可能存在某种漏洞,因此即使它是图像,将其传递给用户也是不安全的。您真的应该调整它的大小以创建一个新的“安全”jpeg,然后将其提供给用户。您可以根据需要制作一个相同大小的新 jpg,但将原始数据传递给其他用户是危险的。
我什至不允许您网站的管理员用户访问随机互联网用户上传的 jpg。它可以用来入侵管理员的电脑。
【讨论】:
$_FILES["file"]["type"] 由用户的浏览器提供,因此对安全无用。
如您所见,文件扩展名也很容易伪造。
如果要确保图像是图像,最简单的方法是在其上运行getimagesize()。
如果您想确保超级并删除可能嵌入图像中的任何和所有元数据,请使用 GD 的 imagecreatefromstring() 将图像复制到空画布(但要为可能的轻微质量损失。)
对于其他文件类型,现在显然有Fileinfo library。它使用底层操作系统的 mime.magic 文件通过检查文件中的某些特征和“标题字节”来估计文件的类型。
【讨论】:
如果您只是处理图像文件,那么 getimagesize() 应该这样做: http://www.php.net/manual/en/function.getimagesize.php
它将图像类型作为它返回的数组的元素返回,如果文件不是有效图像,则返回 FALSE。
【讨论】:
使用 end(explode(".", $name) 时要注意双重扩展。 如果给出了映射到相同元信息的 2 个扩展,Apache 将读取最右边的扩展。例如。 file.gif.html 将被关联为一个 html 文件。
如上所述,客户端提供的浏览器信息作为安全措施是无用的。
最佳选择 - getimagesize(); 与所有事情一样,有很多方法可以解决它。可以在图片中添加恶意代码注释,绕过getimagesize()检查,因为header仍然有效
【讨论】:
getimagesize()是最好的选择;虽然没关系;没有做任何事情来否定代码可以注入真正的 JPEG 等。