Friday, January 1, 2010

Securing File Upload Feature

When an web app allows client to upload file, then the web app may be exploited to upload evil script, backdoor ... The problem is how to not only allow upload feature but also protect your webapp ?
First, we need to understand the basic of upload feature, see the PHP script to handle file upload below:
//Сheck that we have a file
if((!empty($_FILES["uploaded_file"])) && ($_FILES['uploaded_file']['error'] == 0)) {
  //Check if the file is JPEG image and it's size is less than 350Kb
  $filename = basename($_FILES['uploaded_file']['name']);
  $ext = substr($filename, strrpos($filename, '.') + 1);
  if (($ext == "jpg") && ($_FILES["uploaded_file"]["type"] == "image/jpeg") && 
    ($_FILES["uploaded_file"]["size"] < 350000)) {
    //Determine the path to which we want to save this file
      $newname = dirname(__FILE__).'/upload/'.$filename;
      //Check if the file with the same name is already exists on the server
      if (!file_exists($newname)) {
        //Attempt to move the uploaded file to it's new place
        if ((move_uploaded_file($_FILES['uploaded_file']['tmp_name'],$newname))) {
           echo "It's done! The file has been saved as: ".$newname;
        } else {
           echo "Error: A problem occurred during file upload!";
      } else {
         echo "Error: File ".$_FILES["uploaded_file"]["name"]." already exists";
  } else {
     echo "Error: Only .jpg images under 350Kb are accepted for upload";
} else {
 echo "Error: No file uploaded";
Now then think: - How can the php script above protect your webapp ? => It can protect uploaded files from being overwritten and just allow JPG file type can be uploaded. But: It quite simple to trick the webserver to bypass file type when upload, so the client can upload the evil script. And now we need a solution for restrict the execute of uploaded scripts. If using Apache, we can put a .htaccess file in the "upload" folder (chmod -w if you want more security) with the content like this (many ways to use):
Options -ExecCGI
AddHandler cgi-script .php .php3 .php4 .phtml .pl .py .jsp .asp .htm .shtml .sh .cgi

The other way we can rename uploaded files if the ext name is not in our ext acceptable list. Ex:
abc.def => abc.jpg
abc.def.ghi => abc.jpg

If IIS ? :D

No comments:

Post a Comment