php 文件上传校验_验证-如何检查PHP中已上传文件的文件类型?

这篇博客讨论了在PHP中验证上传文件类型的最佳实践。传统的MIME类型检查和扩展名检查存在缺陷,容易被伪造。建议使用`mime_content_type`或`Fileinfo`函数来查看文件内容以确定类型。此外,还可以考虑针对特定文件类型(如PDF、图像或文本文件)使用特定的验证方法,如图像尺寸检查或XML验证。
摘要由CSDN通过智能技术生成

验证-如何检查PHP中已上传文件的文件类型?

在PHP网站上,他们建议的唯一实际检查是在此处使用getimagesize()或move_uploaded_file()。 当然,出于多种原因,您通常不希望用户上传任何类型的文件。

因此,我经常使用一些“严格”的MIME类型检查。 当然,这是非常有缺陷的,因为通常哑剧类型是错误的,并且用户无法上传其文件。 伪造和/或更改也非常容易。 除此之外,每种浏览器和操作系统对它们的处理方式也不同。

另一种方法是检查扩展名,这当然比mime类型更容易更改。

如果只需要图像,则可以使用像getimagesize()这样的图像。

那其他类型的文件呢? PDF,Word文档还是Excel文件? 甚至是纯文本文件?

编辑:如果您没有mime_content_type或Fileinfo,并且system(“ file -bi $ uploadedfile”)给您错误的文件类型,还有哪些其他选择?

7个解决方案

33 votes

看一下mime_content_type或Fileinfo。 这些是内置的PHP命令,用于通过查看文件内容来确定文件的类型。 还要检查以上两页上的评论,还有其他一些好的建议。

就我个人而言,我运气很好,基本上使用了system("file -bi $uploadedfile"),但我不确定这是否是最好的方法。

davr answered 2020-06-20T03:00:00Z

14 votes

恕我直言,所有MIME类型检查方法都没有用。

假设您的文件应具有MIME类型application/pdf。标准方法试图查找看起来像PDF标头的文件(%PDF-或smth。类似这样),它们将在上面返回“好吧,好像这是PDF文件” 成功。 但这实际上并不代表任何意义。 您可以上传仅包含%PDF-1.4的文件,该文件将通过MIME检查。

我的意思是,如果文件具有预期的MIME类型-它将始终通过MIME类型检查,否则结果不确定。

Sudden Def answered 2020-06-20T03:00:29Z

2 votes

我假设您将要接受一个固定的文件类型白名单。

对于每种类型,您将不得不使用不同的技术来验证它们是否是该格式的有效示例。

有两个相关的问题:

它看起来大概像是正确的类型吗? (如前所述,对于JPEG,您可以检查标题。对于许多基于Unix的格式,您可以检查“魔术cookie”。)

它实际上是该类型的有效示例吗(例如,对于任何类似XML的格式,您可以针对DTD进行验证。)

我认为,对于每种格式,您应该针对每种格式分别提出问题,因为与ZIP文件相比,PDF的答案将大不相同。

Oddthinking answered 2020-06-20T03:01:12Z

2 votes

我使用了与PHP 5.2兼容的mime_content_type,因为我不能使用被提供商禁用的Fileinfo(需要PHP 5.3)和system()。例如,我检查文件是否为文本文件,因此:

if (strcmp(substr(mime_content_type($f),0,4),"text")==0) { ... }

您可以在以下位置的“ PHP目录和子目录侦听器以及文件查看器和下载器”中查看完整的示例:[http://www.galgani.it/software_repository/index.php]

Francesco Galgani answered 2020-06-20T03:01:36Z

2 votes

if(isset($_FILES['uploaded'])) {

$temp = explode(".", $_FILES["uploaded"]["name"]);

$allowedExts = array("txt","htm","html","php","css","js","json","xml","swf","flv","pdf","psd","ai","eps","eps","ps","doc","rtf","ppt","odt","ods");

$extension = end($temp);

if( in_array($extension, $allowedExts)) {

//code....

} else {

echo "Error,not Documentum type...";

}

}

Krausz Lóránt Szilveszter answered 2020-06-20T03:01:52Z

1 votes

这是iZend的功能file_mime_type:

function file_mime_type($file, $encoding=true) {

$mime=false;

if (function_exists('finfo_file')) {

$finfo = finfo_open(FILEINFO_MIME);

$mime = finfo_file($finfo, $file);

finfo_close($finfo);

}

else if (substr(PHP_OS, 0, 3) == 'WIN') {

$mime = mime_content_type($file);

}

else {

$file = escapeshellarg($file);

$cmd = "file -iL $file";

exec($cmd, $output, $r);

if ($r == 0) {

$mime = substr($output[0], strpos($output[0], ': ')+2);

}

}

if (!$mime) {

return false;

}

if ($encoding) {

return $mime;

}

return substr($mime, 0, strpos($mime, '; '));

}

iZend answered 2020-06-20T03:02:12Z

0 votes

对于PHP> = 5.3.0,可以使用php的file(finfo_file)函数获取有关文件的文件信息。

对于PHP <5.3.0,可以使用系统的file命令来获取文件信息。

因此,只需使其成为一个函数,

var_dump(mime_type("wiki templete.txt")); // print string(10) "text/plain"

function mime_type($file_path)

{

if (function_exists('finfo_open')) {

$finfo = new finfo(FILEINFO_MIME_TYPE, null);

$mime_type = $finfo->file($file_path);

}

if (!$mime_type && function_exists('passthru') && function_exists('escapeshellarg')) {

ob_start();

passthru(sprintf('file -b --mime %s 2>/dev/null', escapeshellarg($file_path)), $return);

if ($return > 0) {

ob_end_clean();

$mime_type = null;

}

$type = trim(ob_get_clean());

if (!preg_match('#^([a-z0-9\-]+/[a-z0-9\-\.]+)#i', $type, $match)) {

$mime_type = null;

}

$mime_type = $match[1];

}

return $mime_type;

}

MimeTypes

Kris Roofe answered 2020-06-20T03:02:45Z

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值