2

Ok here is my code for uploading files

 $ext_whitelist = array('pdf','doc','doc','mkv','mp4','mpg','mpeg','avi','flv','wma','ogg');

 if(in_array($ext, $ext_whitelist))
 {
     $uniqid_file = uniqid('', true)."_".$file['name'];
     $lokacija = $folder . "/" . $uniqid_file;
     $encoded_uniqid_file = base64_encode($uniqid_file);
     move_uploaded_file($file['tmp_name'], $lokacija);
     $base_url= base_url("forms/fdownload/$encoded_uniqid_file/$path");
     $form_data[$key] = "<a href=".$base_url.">$uniqid_file </a>";
 }

This checks file extension, so easy some could rename file, can someone help me to check file type proper?

9
  • 2
    you can look into mime_type Commented Dec 24, 2014 at 10:15
  • can you write for me Commented Dec 24, 2014 at 10:32
  • SplFileInfo Commented Dec 24, 2014 at 10:43
  • 1
    @teeyo: The easiest way to check the extension. For example: $ext 7=array_pop(explode(".", $fileName)); Then compare it whit a whitelist. It doesn't matter if you can upload a script in .txt, .jpg, .doc ect, because the servers are configured to parse files with php parser if they have extension like: .php, .php5 etc. If you don't allow these, its good. Commented Dec 24, 2014 at 11:35
  • 2
    @teeyo: Another good way to rename the file completly and drop the extension. For example create a hash (md5, sha1, etc) for the file name and if you need, store the original name, extension, mimetype in a database. Commented Dec 24, 2014 at 11:36

2 Answers 2

1

Insted of a comment, I'll write a bit more as an answer.

Mimetype checking is a good thing if you want to know the type of the file, but it's not secure if you want to allow/deny the files at upload, because it's very easy to fake the mimetype. Just try it, you can change it with a proxy or you can create a simple image, then add some php code at the end and rename it to .php. If you only check the mimetype, you can upload this .php file and run it on the server.

If you upload .jpg with php code in it, it's okay, the server won't push it through the php parser. (Except when you change the default configuration. (Apache: AddType, nginx: AddHandler )

There are some "secure" ways to check the uploaded files:

1. Check the extension and compare it to a whitelist.

This is the example in the question, but I'd like to write a complete solution. (A common mistake to check only the first think after the ., because there could be file names like: something.txt.php so always check the last postfix.)

$ext = array_pop(explode(".", $fileName));
$whitelist = array('pdf','doc','doc','mkv','mp4','mpg','mpeg','avi','flv','wma','ogg');

if (in_array($ext, $whitelist) {
  //OK the extension is good, handle the upload.
} else {
  //Wrong type, add error message.
}

If you use something like this, be careful and never allow extensions like .php and anything wich is in the server config.

2. Rename the file and drop the extension.

This is an another good way, but maybe you want to keep the original file name, the extension and the mimetype. You can store them in a database!

For this solution just take the original filename, add some random data (because if you upload into a single folder and you trie to upload something.jpg 2 time that would be a bad idea), then store this. For example:

$newName = sha1($fileName.time());
move_uploaded_file($file['tmp_name'], $uploadPath . $newName);

Because the file doesn't have an extension, the server wont try to run it. (But if it's for example an image it'll work in the browsers, because they use the mimetype to determine the type and we didn't changed that.)

Sign up to request clarification or add additional context in comments.

Comments

1

You can use

perl-file-mimeinfo

Ex:-

$file_path = '/tmp/temp.jpg';
$mimetype = trim(shell_exec("/usr/bin/mimetype -bi ".escapeshellarg($file_path)));
$info = null;
if(strpos($mimetype, "video/")===0 || strpos($mimetype, 'x-flash-video') > 0){
  $info = 'video';
}elseif(strpos($mimetype, "audio/")===0){
  $info = 'audio';
}elseif(strpos($mimetype, "image/")===0){
  $info = 'image';
}

7 Comments

You can, but it's very easy to change. You can upload a .php file with audio/video mime type. So be careful and check the extension too.
could you help me form my example to check is video file or doc docx or pdf format. this is check for uploading video or cv
The original code was good, use that for allowing the upload, then use this mimetype check for getting the type of the file.
Please use echo $mimetype; to check file type. It will give you an idea and use it with if statement.
@Gerifield Yes you are right.Its already handled in question.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.