$_FILES["file"]["type"]和end(explode(".", $_FILES["file"]["name"]))之间有什么区别?

8
我会尽力为您翻译以下内容,涉及编程方面:

我使用 var_dump(@$_FILES['file']['type']) 来测试我上传的文件类型

首先,我上传了一个名为 "uninstall.exe" 的 exe 文件,它返回了

"string 'application/octet-stream' (length=24)"

然后,我将这个文件重命名为uninstall.png,它返回
string 'image/png' (length=9)

我的结论是:$_FILES ['file'] ['type'] 仅检查文件扩展名,而不检查原始文件类型。
下面的代码来自w3cschool
$allowedExts = array("gif", "jpeg", "jpg", "png");
$extension = end(explode(".", $_FILES["file"]["name"]));
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/jpg")
|| ($_FILES["file"]["type"] == "image/png"))
&& ($_FILES["file"]["size"] < 20000)
&& in_array($extension, $allowedExts))

我认为上面代码中的$_FILES["file"]["type"]是不必要的,我们可以使用explode()in_array()来检查文件扩展名。

我只是一个PHP初学者,有人能确认我的想法吗?谢谢!


1
是的,我相信很多人都知道文件类型可以被欺骗。 - Class
4
一次不使用w3schools的教训 - SomeShinyObject
1
谢谢,我很高兴在w3cschool找到了一些问题。 - Eathen Nutt
$_FILES['file']['type'] 不检查扩展名 - 它是从用户机器发送的请求头中的信息。它可以用作提示(对于在用户机器上可识别但在服务器上不可识别的非标准文件格式),但在安全方面不应被信任。 - dev-null-dweller
1
@user1970939 在w3schools上找到问题并不难...(还请注意这不是w3cschools而是w3schools) - dev-null-dweller
3个回答

7

您说得非常正确。 MIME类型由客户端提供,您无法保证它是正确的。同样,文件扩展名也是如此。如果您需要完全确定,您需要查看文件内容。


我很高兴我的想法得到了确认,有人说:“文件的扩展名和'文件类型'可以不同,因此某些人无法使用$_FILES["file"]["type"]上传具有.png扩展名的可执行文件。” 我认为他是错的。 - Eathen Nutt
@user1970939:嗯,有人实际上可以提供一个名为 file.exe 的文件,并将其 MIME 类型设置为 image/png。它们都由客户端提供,不需要保持一致。 - icktoofay

7
如果您想确保图片已经上传,请使用getimagesize函数,它会返回0表示非图片文件。

甚至还有一些JPEGs,大多数来自数码相机。 - Emery King
感谢提到getimagesize。 - Eathen Nutt
1
@darthmaim 绝对不正确!getimagesize可以并且会成功地返回一些非图像的结果。请参见这里 - jdrake
1
官方的PHP文档中明确指出不要使用getimagesize函数。"不要使用getimagesize()函数来检查给定的文件是否为有效图像。而应该使用专门的解决方案,如Fileinfo扩展。" - Edward

1
你应该使用GD或Imagick扩展的封装器。一个非常好的选择是WideImage

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