1

I want to upload images to my server from browser window. However, the upload field will be visible for everyone, so I need to set up some restrictions. I've only found the w3schools file upload (and as of w3fools.com I don't trust it). I want the restrictions to be:

Maximum size 2,5M

Image types jpg, jpeg, png, gif

So here's the code that w3schools provides, but it won't actually save the file anywhere? I've modified it a bit to meet my needs.

<?php
$allowedExts = array("jpg", "jpeg", "gif", "png");
$extension = end(explode(".", $_FILES["file"]["name"]));
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpg")
|| ($_FILES["file"]["type"] == "image/jpeg"))
|| ($_FILES["file"]["type"] == "image/png"))
&& ($_FILES["file"]["size"] < 2500000)
&& in_array($extension, $allowedExts))
  {
  if ($_FILES["file"]["error"] > 0)
    {
    echo "Error: " . $_FILES["file"]["error"] . "<br />";
    }
  else
    {
    echo "Upload: " . $_FILES["file"]["name"] . "<br />";
    echo "Type: " . $_FILES["file"]["type"] . "<br />";
    echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
    echo "Stored in: " . $_FILES["file"]["tmp_name"];
    }
  }
else
  {
  echo "Invalid file";
  }
?>

And as I don't want my site to be hacked, I want a secure solution, any help on this?

Edit

The code doesn't even do anything. So how should I do it?

8
  • I think you should look at stackoverflow.com/a/10271295/1226894 it answers your question Commented Sep 27, 2012 at 8:48
  • Since you are only accepting images you can also look at stackoverflow.com/a/10464964/1226894 it tell you how best to detect fake images Commented Sep 27, 2012 at 8:54
  • @Baba I used the code you provided, and gone outside with my dog. As I came back, my wordpress site was replaced by !X!X HACKED BY RUSSIAN PEOPLE !X!X and a russian flag under it. I took a look at the image upload, and noticed some weird files under the upload folder and in the index folder there was a hack.php which I'll take a look at. However, the file's were uploaded with your script and my site was hacked. How? Commented Sep 27, 2012 at 10:47
  • That might not be the only hole you have in your site ... you entire site would need to be checked Commented Sep 27, 2012 at 10:49
  • 2
    @Baba it is true that your code contains security holes, however I think that you should not remove it as simplified examples are best for most (easier to read and understand). Depending on server versions / configuration it could be that simple null char attack is enough for skipping your extension checks and if server is configured so that everyone can exec any .php file from any directory just by sending HTTP request... no need to explain anymore. Never trust any user input and sanitize with functions that can handle any binary sequences not just plain text. Or use templates for data. Commented Sep 27, 2012 at 18:34

4 Answers 4

3

You need to use php move_upload_file function and also I have made changes to your if statement here is the working and tested example:

<?php

if (isset($_REQUEST["submit"])) {

    $allowedExts = array("jpg", "jpeg", "gif", "png");
    $extension = end(explode(".", $_FILES["file"]["name"]));

    if ($_FILES["file"]["type"] == "image/gif" || $_FILES["file"]["type"] == "image/jpg" || $_FILES["file"]["type"] == "image/jpeg" || $_FILES["file"]["type"] == "image/png" && $_FILES["file"]["size"] < 2500000 && in_array($extension, $allowedExts)) {

      if ($_FILES["file"]["error"] > 0) {

        echo "Error: " . $_FILES["file"]["error"] . "<br />";

      }
      else {

        $fname = $_FILES["file"]["name"];
        move_uploaded_file($_FILES["file"]["tmp_name"], $fname);

        echo "Upload: " . $_FILES["file"]["name"] . "<br />";
        echo "Type: " . $_FILES["file"]["type"] . "<br />";
        echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
        echo "Stored in: " . $fname;

      }

    }
    else {

      echo "Invalid file type";

    }

}
?>
<form action="" method="post" enctype="multipart/form-data">
<input type="file" name="file" />
<input type="submit" name="submit" value="submit" />
</form>

You can also use getimagesize function as suggested by doing next thing:

$size = getimagesize("http://www.simplestudio.rs/060620121945.jpg");

$file_format = $size['mime'];

$file_format will be represented as for example "image/jpeg" so you can easily check for image types like this:

foreach($allowedExts as $allowed) {

$chk_types = strpos($file_format, $allowed);

if($chk_types > -1) {
$type_is_good = true;
break;
}

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

2 Comments

Yeah, it adds the image, and shows the information about it, but is it safe? I tried to upload a .crx file and it failed, but is there any ways to get trough it?
I have edited my answer to add use of getimagesize as it is much more secure than $_FILES["file"]["type"]. Aside of that you can check for user agent as a basic check for bots (even this could be faked by bot). But feel free to google for some more info on image upload security...
1

Use : move_uploaded_file, See, Manual

And one more thing,

the $_FILES["file"]["type"] variable is not good to use as this can be changed by the browser settings.

Use getimagesize instead, See, Manual

Comments

0
  1. $ratio2) { $thumb_w=$new_w; $thumb_h=$old_y/$ratio1; } else { $thumb_h=$new_h; $thumb_w=$old_x/$ratio2; }
        $dst_img=ImageCreateTrueColor($thumb_w,$thumb_h);
    
        imagecopyresampled($dst_img,$src_img,0,0,0,0,$thumb_w,$thumb_h,$old_x,$old_y);
    
                if(!strcmp("png",$ext))             imagepng($dst_img,$filename);       else            imagejpeg($dst_img,$filename); 
            imagegif($dst_img,$filename);
                imagedestroy($dst_img);         imagedestroy($src_img);   }  }  if(!function_exists('getExtension'))    {       function
    
    getExtension($str) { $i = strrpos($str,"."); if (!$i) { return ""; } $l = strlen($str) - $i; $ext = substr($str,$i+1,$l); return $ext; } }
    $image=$_FILES["$imagename"]['name'];   if($image)      {  
        $filename = stripslashes($_FILES["$imagename"]['name']); 
        $extension = getExtension($filename);       $extension =
    
    strtolower($extension); if (($extension != "jpg") && ($extension != "jpeg") && ($extension != "png") && ($extension != "gif") && ($extension != "bmp")) {
            $obj->set_flash("Unknown extension...!");           header("Location: $filename ");             exit;       }       else        {
    
            $size=getimagesize($_FILES["$imagename"]['tmp_name']);
            $sizekb=filesize($_FILES["$imagename"]['tmp_name']);
    
            if ($sizekb > MAX_SIZE*1024)
            {
                $obj->set_flash("You have exceeded the size limit...!");
                header("Location: $filename");
                exit;
            }
    
        $select_max = $obj->sql_query("select max($fieldname) as MaxID from  ".$tablename."");
                        if($action=="Add")          {
                $Max = $select_max[0]['MaxID'];
                $image_name = $Max + 1;
                $new_name = $image_name.".".$extension;//the new name will be containing the full path where will be stored (images folder)
                $$imagename = $new_name;//New Name of Image same as Image Field Name
                $thumbfilename = $new_name;
                $newname="$uploadpath/large/".$new_name;
    
                $copied = copy($_FILES["$imagename"]['tmp_name'], $newname);
                //we verify if the image has been uploaded, and print error instead
                if (!$copied) 
                { 
                    $obj->set_flash("Copy unsuccessfull...!");
                    header("Location: $filename");
                    exit;
                }
                else
                {
                    $thumb_name="$uploadpath/thumb/".$thumbfilename;
                    $thumb=make_thumb($newname,$thumb_name,$WIDTH,$HEIGHT);
                }           }           if($action=="Update")           {
    
                $new_name=$ID.".".$extension;
                $$imagename = $new_name;//New Name of Image same as Image Field Name
                $newname = "$uploadpath/large/".$new_name;
                $thumbfilename = $new_name;
                $copied = copy($_FILES["$imagename"]['tmp_name'], $newname);
    
                if (!$copied) 
                {
                    $obj->set_flash("Copy unsuccessfull...!");
                    header("Location: $filename");
                    exit;
                }
                else
                {
                    $thumb_name="$uploadpath/thumb/".$thumbfilename;
                    $thumb=make_thumb($newname,$thumb_name,$WIDTH,$HEIGHT);
                }           }       }   }       if($action=="Delete")   {       $SelectImage = $obj->sql_query("select $imagename from  $tablename where $fieldname
    
    = ".$$fieldname." "); $ThisImage = $SelectImage[0]["$imagename"]; unlink("$uploadpath/thumb/".$ThisImage); unlink("$uploadpath/large/".$ThisImage); } ?>
    1. List item

1 Comment

Welcome to Stack Overflow. I'm sorry, but I just can't figure out what you're trying to say here. You'll need to reformat your code (I tried; I gave up) and provide some explanation of why it's useful.
0
<?php

          $file_name   = $_FILES['file']['name'];
          $file_size   = $_FILES['file']['size'];
          $file_tmp    = $_FILES['file']['tmp_name'];
          $file_type   = $_FILES['file']['type'];

          /* variable array for store errors */
          $errors   = [];                   


          /* Check if file already exists in location file save */
          $file_dir  = "uploads";
          /** if folder not exists, then create it **/
          if (!file_exists($file_dir)) {
            mkdir($file_dir, 0777, true);
          }

          $file_target = $file_dir . $file_name;
          if (file_exists($file_target)) {
            //$errors[] = "Sorry, <strong>{$file_name}</strong> already exists.";
          }


             /* Check file size */
          if ($file_size > 2500000) {
            $errors[] = "Sorry, <strong>{$file_name}</strong> is too large. It size is {$file_size} > 2500000 bytes";
          }


          /* Check current file formats with file secure */
          $file_secure  = array('jpg', 'jpeg', 'png', 'gif');                   
          $file_current = strtolower(pathinfo($file_name, PATHINFO_EXTENSION)); /* (end(explode('.', $file_name) */

          if (in_array($file_current, $file_secure) === false) {
            $errors[] = "Sorry, <strong>{$file_current}</strong> extension not allowed";            
          }


          /* Check if Errors exist, then not upload. Or if Errors NOT exist, then try upload */
          if (!empty($errors)) {                            

            /* display error */                 
            foreach ($errors as $keyError => $valueError) {
              echo "$keyError = $valueError <br />";
            }

            echo "<br />";
            echo "<strong>{$file_name}</strong> could not uploaded. <hr />";                            

          } else {

            if (move_uploaded_file($file_tmp, $file_target)) {

              echo "Upload: "    . $file_name . "<br />";
              echo "Type: "      . $file_type . "<br />";
              echo "Size: "      . ($file_size / 1024) . " Kb<br />";
              echo "Stored in: " . $file_tmp;

            } else {

              echo "Invalid file";

            }

          }

?>

Comments

Your Answer

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