Here is a simple file upload form
The code is as follows |
Copy Code |
<form action= "upload.php" method= "post" enctype= "Multipart/form-data" Name= "Form1" > <input type= "File" Name= "File1"/><br/> <input type= "Submit" value= "Upload file"/> <input type= "hidden" name= "max_file_size" value= "1024"/> </form> |
PHP's configuration file php.ini, where the option upload_max_filesize specifies the file size to be uploaded, by default 2M
$_files array variable
PHP uses variable $_files to upload files, $_files is an array. If you upload test.txt, then the contents of the $_files array are:
The code is as follows |
Copy Code |
$FILES Array { [File] => Array { [Name] => test.txt//file name [Type] => text/plain//mime type [Tmp_name] =>/tmp/php5d.tmp//Temporary files [ERROR] => 0//error message [Size] => 536//File size, unit byte } } |
If the Upload file button's Name property value is file
The code is as follows |
Copy Code |
<input type= "File" name= "file"/> |
Then use $_files[' file ' [' name '] to get the client upload file name, without the path. Use $_files[' file ' [' Tmp_name '] to obtain a temporary file path for the server to save uploaded files
folder where uploaded files are stored
PHP does not directly upload files to the site root directory, but to save as a temporary file, the name is the value of $_files[' file ' [' Tmp_name '], the developer must copy the temporary file to the stored Web site folder.
The value of the $_files[' file ' [' Tmp_name '] is set by PHP and, unlike the original name of the file, the developer must use $_files[' file ' [' name '] to get the original name of the uploaded file.
Error message when uploading files
The $_files[' file ' [' ERROR '] variable is used to save error messages when uploading files, and its value is as follows:
Error message Numerical description
UPLOAD_ERR_OK 0 No mistakes
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 max_file_size value in the HTML form
Upload_err_partial 3 upload only part of the file
Upload_err_no_file 4 No File Upload
File Upload Vulnerability
If you provide site visitors with the ability to upload pictures, it must be careful that visitors upload the actual may not be pictures, but can specify the PHP program. If the directory that holds the picture is an open folder, the intruder can execute the uploaded php file remotely to attack it.
Here is a simple example of file upload:
code is as follows |
copy code |
<?php //Set the directory of uploaded files $uploaddir =" d:/www/images/"; //Check if file exists if (isset ($_files[' file1 ')) { //the full path to place in the site directory, including file name $ UploadFile = $uploaddir. $_files[' file1 ' [' name ']; //The path to the server, moving to the real file name move_uploaded_file ($_files[' file1 '] [' tmp_name '], $uploadfile); } ? ... <form method= "POST" enctype= "Multipart/form-data" Name= "Form1" <input type= "file" name= File1 "/><br/> <input type=" Submit "value=" Upload file "/> <input type=" hidden "name=" M Ax_file_size "value=" 1024/> </form> |
This example does not verify the file suffix, you can upload arbitrary files, very obvious upload vulnerabilities, to solve the above problem is very simple, we look at 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 allow uploading doc,docx,xls,pdf,ppt file <a href= ' wend.php ' > re-upload </a> ');
} |
This is used to restrict the user to upload the type number or suffix name, so you can filter the simple cannot upload php directly, but we look at an example, you draw the discovery is too terrible.
Use the Paint tool to create a new picture format, such as GIF or JPG or PNG, that starts with a JPG or GIF or PNG.
Write the head of the PHP Web horse to GIF as shown:
The code is as follows |
Copy Code |
Then write a simple php upload file processing (I am in a hurry to write casually, no beauty):
<?php if ($_files) { Echo ' Below is the wrong $_files:<br/> '; echo "<pre>"; Print_r ($_files); echo "</pre>"; echo "Below is the wrong getimagesize () <br/>"; echo "<pre>"; Print_r (getimagesize ($_files[' bug '] [' tmp_name ']); echo "</pre>"; Exit $fp = fopen ($_files[' bug '] [' tmp_name '], "R"); $content = Fread ($fp, filesize ($_files[' bug '] [' tmp_name ']); Echo $content can see the uploaded source code } ?> <form action= "" method= "Post" enctype= "Multipart/form-data" > <input type= "file" name= "Bug"/> <input type= "Submit" > </form> |
You can see the effect of such a pit dad.
The first is that Print_r ($_files) directly displays the extended JPG results.
Then the result of the PHP function getimagesize () is the GIF (it is judged by the beginning of the file).
PHP is unresolved on this issue, but we can operate from the server directory permissions, and here are some solutions.
In fact, we grasp a few places can, we first to analyze, since the user to save files, and the file will be a variety of formats, there may be file content and user incoming format inconsistent, and some file content is also mixed with Trojan code. So, we allow users to save files, and site files to do a separate authorization, do quarantine.
To keep the saved directory separate, directory permissions read-only cannot be performed
This step is authorized from the system design, no matter what file you last, it is impossible to execute. Even if I do not do any testing, your files are stored here, it will not make my system security. (If there is a user to save some of the reactionary language pictures, which need to deal with)
Do not use server incoming values directly, all are checked
This kind of is the same as we do all input is harmful principle, for the client incoming: type, name, are to be judged, not directly used. For a directory to be generated, a filename.
The best way to file names is to write your own dead directory (do not read incoming directories), file names, preferably randomly generated, do not read user file names. File name extension, you can take the rightmost "." Back character.
The above 2 methods, just from the 2 aspects of the total constraint on the deposit.
Method 2: Save the stored file name, write to the directory you specified, and the file name builds itself.
Method 1: As long as the file is written to the right location, and then from the configuration, to write directory permissions control, this is the root causes. Can do, you no matter what file, you do not have the authority to jump out to run.
The above 2 methods, used together, can ensure that files are stored correctly, and then permissions can be controlled. Here, by the way, to determine whether the user files to meet the requirements of the type, directly check the file extension, as long as the extension to meet to save. Anyway, the implementation of the restrictions, you do not follow the requirements of the content, there is no harm. Anyway, can not be carried out, it will not be much harm.
Correct steps:
1. Read the filename to verify that the extension is in range
2. Define your own generated file name, directory, extension can come from the filename extension. Other values, are configured themselves, do not read the contents of the stored
3. Move files to a new directory (this directory permission setting is read-only)