Blog

PHP

PHP Secure File Upload Script

This article provides a simple php secure file upload and validation function.

As a web developer security should be your top priority. This is never more important than when allowing the upload of files to the server as the scope to initiate an attack increases greatly without the proper checks in place. Below is a function that can be used to upload files to your server in a secure manor.

Only files that have a valid extension and MIME type and that are below a set size limit can be uploaded. For added security when uploading images you can also check that the file is a valid image. Finally, you can randomise the file name to further increase security and reduce the risks associated with allowing users to upload files to your website.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
<?php
/**
 * uploadFile()
 * 
 * @param string $file_field name of file upload field in html form
 * @param bool $check_image check if uploaded file is a valid image
 * @param bool $random_name generate random filename for uploaded file
 * @return array
 */
function uploadFile ($file_field = null, $check_image = false, $random_name = false) {
       
  //Config Section    
  //Set file upload path
  $path = 'c:/xampp/htdocs/'; //with trailing slash
  //Set max file size in bytes
  $max_size = 1000000;
  //Set default file extension whitelist
  $whitelist_ext = array('jpg','png','gif');
  //Set default file type whitelist
  $whitelist_type = array('image/jpeg', 'image/png','image/gif');

  //The Validation
  // Create an array to hold any output
  $out = array('error'=>null);
               
  if (!$file_field) {
    $out['error'][] = "Please specify a valid form field name";           
  }

  if (!$path) {
    $out['error'][] = "Please specify a valid upload path";               
  }
       
  if (count($out['error'])>0) {
    return $out;
  }

  //Make sure that there is a file
  if((!empty($_FILES[$file_field])) && ($_FILES[$file_field]['error'] == 0)) {
         
    // Get filename
    $file_info = pathinfo($_FILES[$file_field]['name']);
    $name = $file_info['filename'];
    $ext = $file_info['extension'];
               
    //Check file has the right extension           
    if (!in_array($ext, $whitelist_ext)) {
      $out['error'][] = "Invalid file Extension";
    }
               
    //Check that the file is of the right type
    if (!in_array($_FILES[$file_field]["type"], $whitelist_type)) {
      $out['error'][] = "Invalid file Type";
    }
               
    //Check that the file is not too big
    if ($_FILES[$file_field]["size"] > $max_size) {
      $out['error'][] = "File is too big";
    }
               
    //If $check image is set as true
    if ($check_image) {
      if (!getimagesize($_FILES[$file_field]['tmp_name'])) {
        $out['error'][] = "Uploaded file is not a valid image";
      }
    }

    //Create full filename including path
    if ($random_name) {
      // Generate random filename
      $tmp = str_replace(array('.',' '), array('',''), microtime());
                       
      if (!$tmp || $tmp == '') {
        $out['error'][] = "File must have a name";
      }     
      $newname = $tmp.'.'.$ext;                                
    } else {
        $newname = $name.'.'.$ext;
    }
               
    //Check if file already exists on server
    if (file_exists($path.$newname)) {
      $out['error'][] = "A file with this name already exists";
    }

    if (count($out['error'])>0) {
      //The file has not correctly validated
      return $out;
    } 

    if (move_uploaded_file($_FILES[$file_field]['tmp_name'], $path.$newname)) {
      //Success
      $out['filepath'] = $path;
      $out['filename'] = $newname;
      return $out;
    } else {
      $out['error'][] = "Server Error!";
    }
         
  } else {
    $out['error'][] = "No file uploaded";
    return $out;
  }      
}
?>

An example of it’s usage is as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
if (isset($_POST['submit'])) {
  $file = uploadFile('file', true, true);
  if (is_array($file['error'])) {
    $message = '';
    foreach ($file['error'] as $msg) {
      $message .= '<p>'.$msg.'</p>';    
    }
  } else {
    $message = "File uploaded successfully";
  }
  echo $message;
}
?>
1
2
3
4
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" enctype="multipart/form-data" name="form1" id="form1">
<input name="file" type="file" size="20" />
<input name="submit" type="submit" value="Upload" />
</form>

Related Posts

Discussion

4 Comment(s)

  1. Inger Gallik

    March 22, 2012 at 10:22 pm

    You are my inspiration , I possess few web logs and rarely run out from to brand.

  2. Octavio Grasmuck

    April 5, 2012 at 3:10 am

    Some truly grand work on behalf of the owner of this website , dead great subject matter.

  3. Dan

    October 7, 2013 at 12:14 pm

    Just an FYI – older versions of IE also use a MIME type of image/pjpeg which will produce an “Invalid file type” error and some jpegs might use an extension of .jpeg instead of .jpg


    //Set default file extension whitelist
    $whitelist_ext = array('jpg', 'jpeg', 'png','gif');
    //Set default file type whitelist
    $whitelist_type = array('image/jpg', 'image/pjpeg', 'image/png','image/gif');

  4. Paul

    February 10, 2014 at 10:12 am

    Saved my life with this script thank you SOOOO much x

Leave a Reply