验证上传的文件是不是是实际的图像文件很重要吗?

Posted

技术标签:

【中文标题】验证上传的文件是不是是实际的图像文件很重要吗?【英文标题】:Is it important to verify that the uploaded file is an actual image file?验证上传的文件是否是实际的图像文件很重要吗? 【发布时间】:2011-09-17 12:39:39 【问题描述】:

假设您可以将任何文件上传到服务器,但文件扩展名必须是“.jpg”。你能上传任何可能损害服务器的东西吗?

我的问题是文件类型验证很慢,如果足够安全,我宁愿只检查文件扩展名。我无法想象可以使用伪装成图像的恶意软件的场景。

我已经看到了使用 getimagesize() 来验证图像的建议,但是这个函数很慢,我不知道它是否有必要,甚至是否有效,以防止恶意软件上传......

非常感谢任何关于此的信息。

【问题讨论】:

检查 MIME 类型不行吗?你真的不想在你的服务器上安装 php 脚本,即使使用 jpg 扩展名它们并没有那么危险(我什至不确定) 我怀疑文件类型检查的缓慢程度与http上传过程本身相当。 函数的速度应该无关紧要,因为您将在上传后直接运行它,无论如何用户都不希望它是即时的。我会说只需使用php.net/manual/en/book.fileinfo.php 并完成它,您将永远不必担心。 @mario 您认为 fileinfo 或 getimagesize 甚至可以有效防止恶意软件吗? @dqhendricks:实际上您可以将代码隐藏在完全有效的 JPEG 或 PNG 文件中。然而,基本的魔术字节验证有助于解决 IE 类型嗅探漏洞。 【参考方案1】:

为了测试图像的安全性,我真的只使用一种方法:只需使用 GD 或您正在使用的任何图像处理库重新创建图像,然后使用新图像。

如果您有更新版本的库,这应该使文件非常安全。

它可能会让你的东西慢一点,但越安全越好。

仅检查文件名末尾是否有“.jpg”将无济于事。该文件仍然可以是任何类型的文件。

希望这有帮助!

【讨论】:

相反,如果你有过时的库版本,如果有漏洞,你就完蛋了。 真的!就我个人而言,我宁愿依靠制作 GD 编码的人,而不是我的人,所以我想说即使是过时版本的图像处理库也会更好! 如果您发送的伪造图像的标题中的图像尺寸过大但尺寸很小,任何库都会失败。发送一堆上传请求,它会吃掉服务器上的资源。 @hakre,“速率限制”应该在服务器级别处理 - 而不是应用程序/PHP 级别。 我可以想象 GDlib 将向系统请求内存 - 并且取决于它的编码方式 - 这可能会超过配置的 PHP 内存限制。请注意,我不知道 PHP 中的 gd 库是否属于这种情况。限制 PHP 进程内存限制总是明智的,在 PHP 自己的内存限制设置旁边。【参考方案2】:

似乎只检查扩展是不安全的。对服务器有害吗?很难说,不知道服务器操作系统,上传文件的权限等。你绝对不想让这些被执行。 通过允许用户上传非图像,然后他们只是重命名为他们的朋友下载它时的真实名称,它当然很容易被滥用。这就是您发现自己无意中托管盗版电影、warez 等的原因。

【讨论】:

我认为这甚至是最重要的一点。这是一个老把戏。另一种是伪造文件头或将其附加到原始文件中。【参考方案3】:

如果您认为getimagesize() 有点太慢(因为我们知道所有上传都以超高速完成;))您也可以尝试fileinfo library。它至少检查文件中的一些字节。它非常快,我每天都使用它来处理应用程序中的数百个文件,它应该可以快速运行。

但是,您不验证您不知道的内容。所以可能首先检查扩展名,确保一个安全的文件名和一个安全的存储,并且它们被正确地发送给客户端。

在让任何图像库接触它之前(这应该包括您网站用户计算机上的图像库),出于安全原因,该文件应该由病毒扫描程序扫描。与getimagesize() 相比,这要慢得多,其他人建议查看文件是否出现<?php 以及防止作为有效负载上传。如果没有通过 PHP 安装安全设置(例如通过 suhosin)阻止包含,这自然包括检查 phar 文件

除了按需病毒扫描之外,由于以前未知的漏洞,应不时检查存储的文件。

因此,其中一部分始终是后台作业。但即使是按需实时检查通常也不会花费太多时间,除非您的应用程序一直在上传。您可能想引入一些上传队列,以便上传已经完成,但在运行必要的任务后,上传者可以使用文件获取。

【讨论】:

【参考方案4】:

不检查它是否是图像的另一个副作用是何时以及是否需要将其显示在网站的某个位置(在用户个人资料、首页等),那么如果它不是真正的图像,它会出现故障,因此您的网站也会出现故障。

至于注入的恶意软件,这取决于您的服务器配置。如果尚未更新以保护漏洞和漏洞利用,那么可以,恶意软件可以渗透(尽管这种情况很少见,但有可能)。

【讨论】:

以上是关于验证上传的文件是不是是实际的图像文件很重要吗?的主要内容,如果未能解决你的问题,请参考以下文章

可以在上传之前在 html 表单上调整图像(客户端)的大小吗?

如何使用 Vue.Js 上传仅图像文件?

如何检查上传的图像是否实际上是图像

如何在表单验证错误中“保留”上传的图像?

使用 javascript/jquery 验证文件上传 [重复]

ios将图像上传到Firebase但是当我尝试下载时却不是这样吗?