Simple Analysis of PHP File Upload Vulnerabilities_PHP Tutorial

WBOY
Release: 2016-07-13 17:11:09
Original
1169 people have browsed it

This problem of file upload vulnerability is not something that exists in PHP. It is just caused by our users who may not have done a good job in program development. The previous ASP also had file upload vulnerability. Let me introduce to you the PHP file upload vulnerability. Simple analysis and solutions.


Below is a simple file upload form

The code is as follows Copy code
 代码如下 复制代码


 

 
 


php configuration file php.ini, the option upload_max_filesize specifies the file size allowed to be uploaded, the default is 2M
 代码如下 复制代码

$FILES

Array

{

        [file] => Array

        {

                [name] => test.txt                //文件名称

                [type] => text/plain                //MIME类型

                [tmp_name] => /tmp/php5D.tmp        //临时文件

                [error] => 0                //错误信息

                [size] => 536                //文件大小,单位字节

        }

}

$_FILES array variable

 代码如下 复制代码

PHP uses the variable $_FILES to upload files, $_FILES is an array. If you upload test.txt, the contents of the $_FILES array are:
The code is as follows Copy code
$FILES Array { [file] => Array           { [name] = & gt; test.txt // file name                                                                                                                                                                                                                                     [type] =>       [tmp_name] =>                                                                                                                                                                                                                                                                                            [error] =>                                                                                                                                                                  [size] => } }
If the name attribute value of the upload file button is file
The code is as follows Copy code

Then use $_FILES['file']['name'] to get the name of the file uploaded by the client, excluding the path. Use $_FILES['file']['tmp_name'] to obtain the temporary file path where the server saves uploaded files

Folder to store uploaded files

PHP will not directly put the uploaded file into the website root directory, but save it as a temporary file. The name is the value of $_FILES['file']['tmp_name']. Developers must copy this temporary file to the stored website folder.

The value of $_FILES['file']['tmp_name'] is set by PHP and is different from the original name of the file. Developers must use $_FILES['file']['name'] to obtain the uploaded file original name.

Error message when uploading files

$_FILES['file']['error'] variable is used to save error information when uploading files. Its value is as follows:

Error message value says
UPLOAD_ERR_OK 0 No errors
UPLOAD_ERR_INI_SIZE 1 The size of the uploaded file exceeds the php.ini setting
UPLOAD_ERR_FROM_SIZE 2 The size of the uploaded file exceeds the value of MAX_FILE_SIZE in the HTML form
UPLOAD_ERR_PARTIAL 3 Upload only part of the file
UPLOAD_ERR_NO_FILE 4 No file uploaded

File upload vulnerability

If you provide the function for website visitors to upload pictures, you must be careful that what the visitors upload may not actually be pictures, but a PHP program that can be specified. If the directory where the images are stored is an open folder, the intruder can remotely execute the uploaded PHP file to carry out the attack.

Here is a simple file upload example:

The code is as follows Copy code
 代码如下 复制代码

// 设置上传文件的目录
$uploaddir = "D:/www/images/";

// 检查file是否存在
if (isset($_FILES['file1']))
{
// 要放在网站目录中的完整路径,包含文件名
$uploadfile = $uploaddir . $_FILES['file1']['name'];
// 将服务器存放的路径,移动到真实文件名
move_uploaded_file($_FILES['file1']['tmp_name'], $uploadfile);
}
?>
……


 

 
 

//Set the directory for uploading files

$uploaddir = "D:/www/images/";
代码如下 复制代码
switch( $extension )
{
case 'application/msword':
$extension ='doc';
break;
case 'application/vnd.ms-excel':
$extension ='xls';
break;
case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
$extension ='docx';
break;
case 'application/vnd.ms-powerpoint':
$extension ='ppt';
break;
case 'application/pdf':
$extension ='pdf';
break;
case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
$extension ='xlsx';
break;
default:
die('只允许上传doc,docx,xls,pdf,ppt文件 重新上传');
   
   }
// Check if file exists if (isset($_FILES['file1'])) { // The full path to be placed in the website directory, including the file name $uploadfile = $uploaddir . $_FILES['file1']['name']; // Move the path stored on the server to the real file name move_uploaded_file($_FILES['file1']['tmp_name'], $uploadfile); } ?> ……

This example does not check the file suffix, and any file can be uploaded. It is an obvious upload vulnerability. It is very simple to solve the above problem. Let's look at it from a piece of code.
The code is as follows Copy code
switch( $extension ) { case 'application/msword': $extension ='doc'; Break; case 'application/vnd.ms-excel': $extension ='xls'; Break; case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': $extension ='docx'; Break; case 'application/vnd.ms-powerpoint': $extension ='ppt'; Break; case 'application/pdf': $extension ='pdf'; Break; case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': $extension ='xlsx'; Break; Default: Die('Only doc, docx, xls, pdf, ppt files are allowed to be uploaded Re-upload');   }

This is used to limit the type number or suffix name uploaded by users. This allows simple filtering and prevents direct uploading of php. But let’s look at another example. You will find it terrible.

Use the drawing tool to create a new image format such as jpg, gif, or png. The beginning must be GIF, JPG, or PNG.

Write the head of the php web horse into GIF as shown in the picture:

The code is as follows Copy code
 代码如下 复制代码


然后写一个简单的php上传文件处理(我赶时间随便写的,没什么美感):

 

if($_FILES){
echo '以下是错误的$_FILES:
';
 echo "

";<br>
 print_r($_FILES);<br>
 echo "
";

 echo "以下是错误的getimagesize()
";
 echo "

";<br>
 print_r(getimagesize($_FILES['bug']['tmp_name']));<br>
 echo "
";
 exit;
 $fp = fopen($_FILES['bug']['tmp_name'],"r");
 $content = fread($fp,filesize ($_FILES['bug']['tmp_name']));
 //echo $content 可以看到上传的源代码
}
?>



Then write a simple php upload file processing (I wrote it casually in a hurry, it has no beauty): echo 'The following is the wrong $_FILES:
';
echo "
";<br>
print_r($_FILES);<br>
echo "
"; echo "The following is the wrong getimagesize()
";
echo "
";<br>
print_r(getimagesize($_FILES['bug']['tmp_name']));<br>
echo "
";
exit;
$fp = fopen($_FILES['bug']['tmp_name'],"r");
$content = fread($fp,filesize ($_FILES['bug']['tmp_name']));
//echo $content You can see the uploaded source code
}
?>

You can see the cheating effect as shown in the picture.


The first is print_r($_FILES), which directly displays the expanded jpg result.
Then the result of the PHP function getimagesize() is gif (it is based on the paragraph at the beginning of the file).

PHP cannot solve this problem, but we can operate it from the server directory permissions. Here are some solutions.

Actually, we just need to focus on a few places. Let’s analyze it first. Since the user wants to save files, and the files will be in a variety of formats; some file contents may be inconsistent with the user’s input format, and some The content of the file also contains Trojan horse code. Then, we let the user save the file, authorize it separately from the site file, and implement isolation.

Make the save and save directories independent. The directory permissions are read-only and cannot be executed
This step is authorized from the system design, no matter what file you last time, it will not be executed. Even if I don't do any testing, if all your files are stored here, it won't pose a security risk to my system. (If there are pictures with reactionary words stored on the user’s website, they need to be dealt with separately)

Do not use the server incoming values ​​directly, all must be detected

This type is the same as our principle that all input is harmful. For the type and name passed in by the client, they must be judged and not used directly. For a certain directory and a certain file name to be generated.

The best way to use the file name is to hard-code the directory yourself (do not read the incoming directory). It is best to randomly generate the file name yourself without reading the user's file name. The file extension can be the characters following the rightmost ".".

The above two methods just put overall constraints on the storage from two aspects.

Method 2: Save the file name, write it in the directory you specify, and generate the file name yourself.

Method 1: Just ensure that the file is written to the correct location, and then configure permission control on the writing directory. This is the root cause. It can be done. No matter what files you save, you will not have permission to jump out and run them.

The above two methods, used together, can ensure that the file is saved in the correct place, and then the permissions can be controlled. By the way, to determine whether the file saved by the user meets the required type, the file extension is directly checked. As long as the extension is met, the file is allowed to be saved. Anyway, with execution permission restrictions in place, it doesn’t matter if you don’t upload the content as required. Anyway, if it can't be implemented, it won't be very harmful.

Correct steps:
1. Read the file name and verify whether the extension is within the range

2. Define the generated file name, directory, and extension by yourself, which can come from the file name extension. All other values ​​are configured by yourself and the contents of the upper memory are not read

3. Move the file to a new directory (the permissions of this directory are set to read-only)

www.bkjia.comtruehttp: //www.bkjia.com/PHPjc/629604.htmlTechArticleThis problem of file upload vulnerability is not something that exists in PHP. It is just that our users may not have done a good job in program development. As a result, the previous ASP also had file upload vulnerabilities. Let me explain below...
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template