使用PHP上传DOC或PDF

时间:2021-12-05 21:22:46

I'm able to upload images fine, but when when I change the types from image/jpg, image/gif to application/msword and application/pdf, it doesn't work. Here's my code. The exact same code works for images, but for uploading docs and pdf, it outputs "Invalid File." What's going on here? My file is only approx 30kb and is well under the file size limit here.

我可以很好地上传图像,但是当我将图像/ jpg,image / gif更改为application / msword和application / 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."
}

6 个解决方案

#1


34  

Don't use the ['type'] parameter to validate uploads. That field is user-provided, and can be trivially forged, allowing ANY type of file to be uploaded. The same goes for the ['name'] parameter - that's the name of the file as provided by the user. It is also trivial to forge, so the user's sending nastyvirus.exe and calling it cutekittens.jpg.

不要使用['type']参数来验证上传。该字段是用户提供的,可以简单地伪造,允许上传任何类型的文件。 ['name']参数也是如此 - 这是用户提供的文件名。伪造也是微不足道的,所以用户发送nastyvirus.exe并将其命名为cutekittens.jpg。

The proper method for validating uploads is to use server-side mime-type determination, e.g. via fileinfo, plus having proper upload success checking, which you do not:

验证上载的适当方法是使用服务器端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(...);

You are also using the user-provided filename as part of the final destination of the move_uploaded_files. it is also trivial to embed path data into that filename, which you then blindly use. That means a malicious remote user can scribble on ANY file on your server that they know the path for, plus plant new files.

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

#2


7  

Please add the correct mime-types to your code - at least these ones:

请在代码中添加正确的mime-types - 至少这些:

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

A list of mime-types can be found here.

可以在此处找到mime类型列表。

Furthermore, simplify the code's logic and report an error number to help the first level support track down problems:

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

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

#3


5  

$folder = "Resume/";
$temp = explode(".", $_FILES["uploaded"]["name"]);
$newfilename = round(microtime(true)).'.'. end($temp);
$db_path ="$folder".$newfilename  ;
//remove the .
$listtype = array(
'.doc'=>'application/msword',
'.docx'=>'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'.rtf'=>'application/rtf',
'.pdf'=>'application/pdf'); 
if ( is_uploaded_file( $_FILES['uploaded']['tmp_name'] ) )
{
if($key = array_search($_FILES['uploaded']['type'],$listtype))
{if (move_uploaded_file($_FILES['uploaded']  ['tmp_name'],"$folder".$newfilename))
{
include('connection.php');
$sql ="INSERT INTO tb_upload
(filePath) VALUES ('$db_path')";
}
}
else    
{
echo "File Type Should Be .Docx or .Pdf or .Rtf Or .Doc";
}

#4


2  

One of your conditions is failing. Check the value of mime-type for your files.
Try using application/pdf, not text/pdf. Refer to Proper MIME media type for PDF files

你的一个条件是失败。检查文件的mime-type值。尝试使用application / pdf,而不是text / pdf。有关PDF文件,请参阅正确的MIME媒体类型

#5


1  

You can use

您可以使用

$_FILES['filename']['error'];

If any type of error occurs then it returns 'error' else 1,2,3,4 or 1 if done

如果发生任何类型的错误,则返回'error',否则返回1,2,3,4或1(如果已完成)

1 : if file size is over limit .... You can find other options by googling

1:如果文件大小超过限制....你可以通过谷歌搜索找到其他选项

#6


-1  

For application/msword and application/vnd.ms-excel, when I deleted the size restriction:

对于application / msword和application / vnd.ms-excel,当我删除大小限制时:

($_FILES["file"]["size"] < 20000)

...it worked ok.

......它运作正常。

#1


34  

Don't use the ['type'] parameter to validate uploads. That field is user-provided, and can be trivially forged, allowing ANY type of file to be uploaded. The same goes for the ['name'] parameter - that's the name of the file as provided by the user. It is also trivial to forge, so the user's sending nastyvirus.exe and calling it cutekittens.jpg.

不要使用['type']参数来验证上传。该字段是用户提供的,可以简单地伪造,允许上传任何类型的文件。 ['name']参数也是如此 - 这是用户提供的文件名。伪造也是微不足道的,所以用户发送nastyvirus.exe并将其命名为cutekittens.jpg。

The proper method for validating uploads is to use server-side mime-type determination, e.g. via fileinfo, plus having proper upload success checking, which you do not:

验证上载的适当方法是使用服务器端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(...);

You are also using the user-provided filename as part of the final destination of the move_uploaded_files. it is also trivial to embed path data into that filename, which you then blindly use. That means a malicious remote user can scribble on ANY file on your server that they know the path for, plus plant new files.

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

#2


7  

Please add the correct mime-types to your code - at least these ones:

请在代码中添加正确的mime-types - 至少这些:

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

A list of mime-types can be found here.

可以在此处找到mime类型列表。

Furthermore, simplify the code's logic and report an error number to help the first level support track down problems:

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

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

#3


5  

$folder = "Resume/";
$temp = explode(".", $_FILES["uploaded"]["name"]);
$newfilename = round(microtime(true)).'.'. end($temp);
$db_path ="$folder".$newfilename  ;
//remove the .
$listtype = array(
'.doc'=>'application/msword',
'.docx'=>'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'.rtf'=>'application/rtf',
'.pdf'=>'application/pdf'); 
if ( is_uploaded_file( $_FILES['uploaded']['tmp_name'] ) )
{
if($key = array_search($_FILES['uploaded']['type'],$listtype))
{if (move_uploaded_file($_FILES['uploaded']  ['tmp_name'],"$folder".$newfilename))
{
include('connection.php');
$sql ="INSERT INTO tb_upload
(filePath) VALUES ('$db_path')";
}
}
else    
{
echo "File Type Should Be .Docx or .Pdf or .Rtf Or .Doc";
}

#4


2  

One of your conditions is failing. Check the value of mime-type for your files.
Try using application/pdf, not text/pdf. Refer to Proper MIME media type for PDF files

你的一个条件是失败。检查文件的mime-type值。尝试使用application / pdf,而不是text / pdf。有关PDF文件,请参阅正确的MIME媒体类型

#5


1  

You can use

您可以使用

$_FILES['filename']['error'];

If any type of error occurs then it returns 'error' else 1,2,3,4 or 1 if done

如果发生任何类型的错误,则返回'error',否则返回1,2,3,4或1(如果已完成)

1 : if file size is over limit .... You can find other options by googling

1:如果文件大小超过限制....你可以通过谷歌搜索找到其他选项

#6


-1  

For application/msword and application/vnd.ms-excel, when I deleted the size restriction:

对于application / msword和application / vnd.ms-excel,当我删除大小限制时:

($_FILES["file"]["size"] < 20000)

...it worked ok.

......它运作正常。