PHP 上传 MIME 类型限制

Posted

技术标签:

【中文标题】PHP 上传 MIME 类型限制【英文标题】:PHP upload MIME type restrictions 【发布时间】:2016-01-25 11:03:27 【问题描述】:

我在一个站点中有一个文件上传系统,它允许上传 .doc、.docs 和 .pdf 文件。目前 php 脚本允许上传任何文件类型。我想限制它只允许上传正版 PDF DOC 和 DOCX 文件。我读过这最好通过检查文件的 MIME 类型/标题来完成 - 但似乎无法在任何地方找到一个公认的最佳解决方案。

关于实现这一目标的最佳方法的任何提示?

当前上传的PHP是:

$meta = $dropbox->UploadFile($_FILES["fileInputFieldName"]["tmp_name"], $upload_name);

请欣赏有关如何将其整合到建议中的任何提示。

【问题讨论】:

***.com/questions/11601342/… 在文件扩展名上使用 if 条件。 【参考方案1】:

为什么不试试下面的代码

$sys = mime_content_type($_FILES["fileToUpload"]["tmp_name"]);
if($sys == 'application/x-zip' || $sys == 'application/msword')
    echo ' allowed';
else
    echo 'not allowed';

【讨论】:

PHP5及以上版本可以使用finfo_file。 感谢贾斯汀,所以,为了实现这一点,我需要更改哪些元素以反映我的文件上传系统。为什么我们需要一个“tmp_name”元素? @dubbs tmp_name 不是元素。它是图像属性【参考方案2】:

我最后为那些感兴趣的人使用了这个:

$allowedExts = array(
  "pdf", 
  "doc", 
  "docx"
); 

$allowedMimeTypes = array( 
  'application/msword',
  'application/pdf',
  'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
  'application/x-pdf',
  'application/vnd.pdf',
  'text/pdf'
);

$extension = end(explode(".", $_FILES["file"]["name"]));

if ( ! ( in_array($extension, $allowedExts ) ) ) 
  die('Please provide another file type [E/2].');


if ( in_array( $_FILES["file"]["type"], $allowedMimeTypes ) ) 
      
 move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $_FILES["file"]["name"]); 

else

die('Please provide another file type [E/3].');

【讨论】:

但是刚刚测试,我拿了一个 JPG 文件,并给它一个 .pdf 文件扩展名,它通过了这个验证...??? 这不安全:type 属性是由浏览器发送的,可以伪造,或者与错误识别类型的浏览器发生冲突(这可能是 JPG 与 PDF 案例中发生的情况) .贾斯汀的答案是唯一安全的答案。【参考方案3】:
that is how i restrict extension for image, you can apply this for doc and other files you want.. 

 "i converted $_FILES to $file"

if ($file['profile_pic']['error'] == 0) 
                                         // echo 'hello';
                                $fileName = strtolower($file['profile_pic']['name']);
                                $fileType = $file['profile_pic']['type'];
                                $tempName = $file['profile_pic']['tmp_name'];
                                $fileSize = $file['profile_pic']['size'];

                                $fileExtArray = array('image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'public.jpeg');
                                $random_no = mt_rand() * 64;
                                $uploaddir = '../../Application/img/';
                                $file_name = $random_no . "_profile_" . $_FILES['profile_pic']['name'];
                                $image = $uploaddir . basename($file_name);
                                if (in_array($fileType, $fileExtArray))
                                    move_uploaded_file($_FILES['profile_pic']['tmp_name'], $image);
                          

【讨论】:

【参考方案4】:
            $allowedExts = array("bmp", "gif", "jpg","png","jpeg");
                            $RandomNum   = rand(0, 9999);           
                            $ImageName      = str_replace(' ','-',strtolower($_FILES['uploadedimage']['name']));
                            $ImageType      = $_FILES['uploadedimage']['type']; //"document/txt", document/doc etc.
                            $ImageExt = substr($ImageName, strrpos($ImageName, '.'));
                            $ImageExt = str_replace('.','',$ImageExt);
                            if (!empty($_FILES["uploadedimage"]["name"]))
                            
                                if(!in_array($ImageExt, $allowedExts))
                                
                                    $message.="<span class='error-message'>Invalid file format of image, only <b>'bmp', 'gif', 'jpg','png','jpeg'</b> allowed.</span><br>";
                                
                            
                            if(isset($message) && $message=='')
                            
                                //image
                                $temp_name=$_FILES["uploadedimage"]["tmp_name"];
                                $imagename=time().'-'.$ImageName;
                                $target_path = "../profile-images/".$imagename;
                                $_SESSION['message']=$message;  
                                

【讨论】:

以上是关于PHP 上传 MIME 类型限制的主要内容,如果未能解决你的问题,请参考以下文章

通过 mime 对 xml 文件的 php 文件上传限制

php文件上传客户端限制和服务器端限制

如何更改文件 mime 类型以绕过 php shell 上传? [关闭]

php 允许其他mime类型进行wordpress上传

php 添加上传zip / rar mime类型

PHP - 使用正确的 MIME 类型打开上传的 DOCX 文件