上传中 Mimetypes 的可靠性 (PHP)
我有一段时间一直有这个问题:文件的 mime 类型到底是如何确定的?我相信这是通过检查文件的特定字节是否包含任何已知的 魔法数字< 来完成的/a> / 文件签名,对吗?
如果是这样,这就提出了另一个问题,假设我将一个带有假 GIF 文件签名的 bash 脚本上传到一个只允许上传图像的网站,会发生什么?或者:
- mimetype 检测例程足够智能,可以检测假签名,或者
image/gif
被错误地返回为 mimetype,并且允许继续上传
我没有安装 ATM 机上的十六进制编辑器,并且我不喜欢从测试中得出与安全相关的结论,因为我可能会错过(或误解)某些内容,所以我的问题是:上述选项中哪一个是正确的?
另外,是否有任何其他最佳实践(除了检查 mimetype 之外)来确保任何给定的文件实际上是它看起来/需要(或允许)的?提前致谢。
PS:需要明确的是,我并不是在询问 $_FILES
超全局中的 type
索引。
I've had this question for a while: how exactly is the mime type of a file determined? I believe this is done by checking if specific bytes of the file contain any of the known magic numbers / file signatures, right?
If so, this poses another question, lets say I upload a bash script with a fake GIF file signature to a website that only allows images to be uploaded, what is going to happen? Either:
- the mimetype detection routine is smart enough to detect fake signatures, or
image/gif
is wrongly returned as the mimetype and the upload is allowed to continue
I don't have an HEX editor installed ATM, and I don't like to form security-related conclusions from tests as I might miss (or misinterpret) something, so my question is: which one of the above options is correct?
Also, are there any other best practices (besides checking the mimetype) to assure that any given file is in fact what it seems / needs (or is allowed) to be? Thanks in advance.
PS: Just to be clear, I'm not asking about the type
index in the $_FILES
superglobal.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我的理解是文件上传代码中的 MIME 确定例程非常粗糙,并且 $_FILES 数组中的 MIME 类型根本不可信。根据我的经验,它很容易被欺骗。
您最好使用 Fileinfo 库,它提供更强大的文件类型检测。
http://www.php.net/manual/en/ref.fileinfo.php
My understanding is the MIME determination routines in the file upload code are extremely crude and that the MIME type in the $_FILES array simply can't be trusted. It's been my experience that it's easily foxed.
You're better off using the Fileinfo library, which provides more robust file type detection.
http://www.php.net/manual/en/ref.fileinfo.php
如果您谈论的是
$_FILES['userfile']['type']
那么此信息是由浏览器发送的。它可能存在,也可能不存在,即使存在,您也应该像对待任何其他用户输入一样对待它。如果您有兴趣检查图像,可以使用 getimagesize 函数来确定文件类型。对于它无法理解的图像,该函数返回 NULL。即使它返回有效的图像类型,您仍然可以拒绝该文件,例如,如果您需要 GIF 和 JPEG,但得到的是 TIFF。
此外,网络服务器将根据文件权限(执行位和shebang行)和文件扩展名来确定是否执行文件。如果你检查这两个,你可能就没事了。
If you're talking about
$_FILES['userfile']['type']
then this information is sent by the browser. It may or may not be present and even if its present you should treat it just like any other user input.If you're interested in checking for images you can use the getimagesize function to determine file type. This function returns NULL for images it cannot understand. Even if it returns a valid image type you can still reject the file e.g. if you're expecting GIF and JPEGs and you get a TIFF instead.
Also, a webserver will determine whether to execute a file of not depending on file permissions (the execute bit and the shebang line) and file extension. If you keep a check on these two you're probably OK.
我的理解是,这(易受攻击的 MIME 类型)是文件名在上传时应通过各种方式加密,然后存储在数据库中以便通过 ID 号检索的原因。基本上,如果有人设法上传恶意脚本,他们将永远无法找到它来运行它?
My understanding is that this (vulnerable MIME types) is the reason that filename's should be encrypted through various means when they're uploaded and then stored in a database to be retrieved via ID numbers. Basically should someone manage to upload a malicious script, they'll never be able to find it to run it?