使用 PHP 上传 DOC 或 PDF

2022-08-30 17:33:30

我可以很好地上传图像,但是当我将类型从image / jpg,image / gif更改为appplication / msword和appplication / pdf时,它不起作用。这是我的代码。完全相同的代码适用于图像,但对于上传文档和pdf,它会输出“无效文件”。这是怎么回事?我的文件只有大约30kb,远远低于这里的文件大小限制。

$allowedExts = array("pdf", "doc", "docx"); 
$extension = end(explode(".", $_FILES["file"]["name"]));

if ( ( ($_FILES["file"]["type"] == "application/msword") || ($_FILES["file"]["type"] == "text/pdf") ) 
&& ($_FILES["file"]["size"] < 20000) && in_array($extension, $allowedExts))
{      
 move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $_FILES["file"]["name"]); 
}
else
{
echo "Invalid file."
}

答案 1

请勿使用该参数来验证上传。该字段是用户提供的,可以轻易伪造,允许上传任何类型的文件。参数也是如此 - 这是用户提供的文件名称。伪造也是微不足道的,因此用户发送并调用它 。['type']['name']nastyvirus.executekittens.jpg

验证上载的正确方法是使用服务器端 mime 类型确定,例如通过 fileinfo,再加上适当的上载成功检查,而您不需要:

if ($_FILES['file']['error'] !== UPLOAD_ERR_OK) {
    die("Upload failed with error " . $_FILES['file']['error']);
}
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $_FILES['file']['tmp_name']);
$ok = false;
switch ($mime) {
   case 'image/jpeg':
   case 'application/pdf'
   case etc....
        $ok = true;
   default:
       die("Unknown/not permitted file type");
}
move_uploaded_file(...);

您还将使用用户提供的文件名作为move_uploaded_files的最终目标的一部分。将路径数据嵌入到该文件名中也是微不足道的,然后盲目地使用它。这意味着恶意远程用户可以在服务器上他们知道路径的任何文件上涂鸦,以及植入新文件。


答案 2

请在代码中添加正确的哑剧类型 - 至少是以下几种:

.jpeg -> image/jpeg
.gif  -> image/gif
.png  -> image/png

可以在此处找到哑剧类型的列表。

此外,简化代码的逻辑并报告错误号,以帮助第一级支持跟踪问题:

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

$allowedMimeTypes = array( 
  'application/msword',
  'text/pdf',
  'image/gif',
  'image/jpeg',
  'image/png'
);

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

if ( 20000 < $_FILES["file"]["size"]  ) {
  die( 'Please provide a smaller file [E/1].' );
}

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].');
}

推荐