In-depth file upload under PHP

Source: Internet
Author: User
Tags php file upload
PHP file upload in layman's conditions


Source: http://www.360weboy.com/php/upload.html

?

File as a special form data, when submitted to the server via an HTTP POST request, PHP generates a $_files global array, and the associated file information is stored in this global array. I will be in this article through some sample code to explain the file upload under PHP, and in-depth look at the implementation of the file upload inside the mechanism, and finally simply how to enhance the security of this area!

File Upload

In order for the client user to be able to upload the file, we must provide a form in the user interface to submit a request to upload the file. Since the uploaded file is a special kind of data, different from other post data, we must set a special code for the form:

1

<form action="upload.php" method="POST" Enctype="Multipart/form-data">

?

Above the enctype attribute, you may not be familiar with it, as this is often ignored. However, if the HTTP POST request has both regular data and file class data, this attribute should be displayed plus, which can improve compatibility for various browsers.

Next, we need to add a field to the form for uploading the file:

1

<input type="file" name="attachment" / >

The above file fields may behave differently in various browsers. For most browsers, the above fields will be rendered as a text box plus a browse button. This allows the user to either enter the path of the file themselves into the text box or select the file to upload from the local hard drive via the browse button. However, in Apple's safari, it seems like you can only use the browse this way. Of course, you can also customize the style of the upload box to make it look more elegant than the default style.

Below, in order to better explain how to deal with file upload, give a complete example. For example, one of the following forms allows users to upload attachments to my local server:

1
2
3
4
5

<p>Please upload your attachment:</P>
<form action="upload.php" method="POST" enctype="Multipart/form-data">
<input type="file" name=" Attachment " />
<input type="Submit" value="Upload attachment" / >
</form>

Tip: You can set the maximum number of files allowed to be uploaded by Upload_max_filesize in php.ini. In addition, there is a post_max_size can also be used to set the maximum allowed to upload the form data, in particular, the form of the sum of the various data, so you can also set this field to control the maximum number of uploaded files. Note, however, that the value of the latter must be greater than the former, because the former belongs to the latter part of the form data.

Figure 1. Upload form displayed in Firefox

When this form is submitted, the HTTP request is sent to upload.php. To show exactly what information can be used in upload.php, I print it out in upload.php:

1
2
3
4
5
6



Header (' Content-type:text/plain ') ;
Print_r ($_files) ;

?>

Below to do an experiment, if I upload a blog logo through the above form to my local server www.360weboy.me/upload.php, see what will be output in the upload.php message:

1
2
3
4
5
6
7
8
9
10
11
12

Array
(
? ?[Attachment] = Array
? ? ? ?(
? ? ? ? ? ?[Name] =Boy.Jpg
? ? ? ? ? ?[Type] =Image/Jpeg
? ? ? ? ? ?[Tmp_name] =D:\xampp\tmp\php1168.Tmp
? ? ? ? ? ?[Error] = 0
? ? ? ? ? ?[Size] = 11490
? ? ? ?)

)

The above is all the information about the current upload file in the global array after the file is uploaded. But can we ensure that this information is safe if name or other information has been tampered with? We always need to be vigilant about the information from the client!

Individual parts of a specific HTTP request

In order to better understand the file upload, we have to check the HTTP request sent by the client in the end contains those specific information. I uploaded the previous attachment is the logo of this blog, because it is a picture, not very suitable for us to do the above experiment. So, I re-upload a test.text text file that contains the following details:

1
2
3
4
5

360weboy

360days

Life's A Web boy

Okay. Now I upload this text file and output it in upload.php:

1
2
3
4
5
6
7
8
9
10
11
12

Array
(
? ?[Attachment] = Array
? ? ? ?(
? ? ? ? ? ?[Name] =Test.Txt
? ? ? ? ? ?[Type] =Text/Plain
? ? ? ? ? ?[Tmp_name] =D:\xampp\tmp\php51c0.Tmp
? ? ? ? ? ?[Error] = 0
? ? ? ? ? ?[Size] = +
? ? ? ?)

)

Let's look at the HTTP POST request sent by the relevant browser (some optional headers I omitted):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

post/upload.php http/1.1
Host:www.360weboy.me
referer:http://www.360weboy.me/
Multipart/form-data; boundary=---------------------------24464570528145
content-length:234
?
-----------------------------24464570528145
Content-disposition:form-data; Name= "Attachment"; Filename= "Test.txt"
Content-type:text/plain

360weboy

360days

Life's A Web boy
-----------------------------24464570528145--

There are several fields in the request format from the above: name, filename, and Content-type, respectively. They represent the field name of the Upload file box in the form form-attachment, and the user uploads the file name from the local hard drive – Test.txt, as well as the uploaded file format –text/plain (representing the text file). Then, we see a line of empty lines below, is the specific content of this upload file.

Security enhancement

To enhance security in file uploads, we need to check the tmp_name and size in the $_files global array. To make sure that the file that the Tmp_name points to is really the file that the user has just uploaded on the client, instead of pointing to a similar/etc/passwd, you can use the function is_uploaded_file () in PHP to make the following decision:

1
2
3
4
5
6
7
8
9


?
$filename = $_files [' attachment '] [' tmp_name '] ;
?
if (is_uploaded_file($filename)) {
? ? / * is an uploaded file. * /
}
?
?>

In some cases, when a user uploads a file, the content of the uploaded file may be displayed to the user, which is especially important for checking the above code.

Another thing to check is the mime-type of the uploaded file, which is the Type field of the output array in the upload.php above. I uploaded a picture in the first example, so the value of $_files[' attachment ' [' type '] is ' image/jpeg '. If you intend to accept only image/png, Image/jpeg, Image/gif, Image/x-png, and image/p-jpeg images on the server side, you can check them with code similar to the following (just for example, the specific code , such as an error, should follow the mechanism in your system):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

$allow _mimes = Array(
? ?' Image/png ',
? ?' Image/x-png ',
? ?' Image/gif ',
? ?' Image/jpeg ',
? ?' Image/pjpeg '
);

$image = $_files[' attachment '];

if(!In_array($image[' type '], $allow _mimes)) {
? ? die(' Sorry, the file format you uploaded is not accurate; we only accept image files. ');
}

//Continue processing the uploaded picture file

As you can see, we have categorization malleability the mime-type of the file is in line with the requirements of the server side. However, it is not enough to prevent malicious users from uploading other harmful files, because this mime-type malicious user can be disguised. For example, a user makes a JPG image, writes some malicious PHP code into the metadata of the image, and then saves it as a file with a suffix called PHP. When this malicious file is uploaded, it will pass through the server side of the Mime-type check, is considered to be a picture, the inside of the dangerous PHP code will be executed. The metadata for the specific picture is similar to the following:

1
2
3
4
5

File name??: Image.jpg
File size??: 182007 bytes
File date??: 2012:11:27 7:45:10
Resolution? : 1197 x 478
Comment???:

We can see that the PHP code is added to the comment field of the picture metadata. Therefore, it is clear that in order to prevent the occurrence of a similar dangerous situation, you must also make a necessary check for the extension of the uploaded file. The following code reinforces the code for the previous check Mime-type:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21st

$allow _mimes = Array(
? ?' Image/png ' = '. png ',
? ?' Image/x-png ' = '. png ',
? ?' Image/gif ' = '. gif ',
? ?' Image/jpeg ' = '. jpg ',
? ?' Image/pjpeg ' = '. jpg '
);

$image = $_files[' attachment '];

if(!array_key_exists($image[' type '], $allow _mimes )) {
? ? die(' Sorry, the file format you uploaded is not accurate; we only accept image files. ');
}

//Get the filename that omitted the suffix name:
$filename = substr($image[' name '], 0, Strrpos($image[' name '], '.'));

//Add suffix name
$filename .= $allow _mimes[$image[' type ']];

//Continue processing the uploaded file

Through the above code, we ensure that even if the uploaded image of the meta-file contains the PHP code, the image file will be the same name as the suffix image format file, so the PHP code will not be executed. The above code will not have any negative effect on normal uploaded images.

After taking the steps above to improve security, if you just want to save the uploaded file to a specified directory, you can use PHP's default function Move_uploaded_file:

1
2
3
4
5
6
7
8
9
10


?
$tmp _filename = $_files [' attachment '] [' tmp_name '] ;
$filename = '/path/to/attachment.txt ' ;
?
if (move_uploaded_file(tmp_filename, $filename) ) {
? ? / * $temp _filename the uploaded file saved in the temp directory and then successfully saved it to the Attachment.txt file in the corresponding directory. * /
}
?
?>

You may also want to limit the size of the upload file, then you can use the FileSize function to get the size of the upload file, after the judgment to do further processing, this is not in this will be, to toss it yourself.

?

  • Related Article

    Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.