Asked  7 Months ago    Answers:  5   Viewed   28 times

I am programming a script to upload images to my application. Are the following security steps enough to make the application safe from the script side?

  • Disable PHP from running inside the upload folder using .httaccess.
  • Do not allow upload if the file name contains string "php".
  • Allow only extensions: jpg,jpeg,gif and png.
  • Allow only image file type.
  • Disallow image with two file type.
  • Change the image name.
  • Upload to a sub-directory not root directory.

This is my script:

 $filename=$_FILES['my_files']['name'];
 $filetype=$_FILES['my_files']['type'];
 $filename = strtolower($filename);
 $filetype = strtolower($filetype);

 //check if contain php and kill it 
 $pos = strpos($filename,'php');
 if(!($pos === false)) {
  die('error');
 }




 //get the file ext

 $file_ext = strrchr($filename, '.');


 //check if its allowed or not
 $whitelist = array(".jpg",".jpeg",".gif",".png"); 
 if (!(in_array($file_ext, $whitelist))) {
    die('not allowed extension,please upload images only');
 }


 //check upload type
 $pos = strpos($filetype,'image');
 if($pos === false) {
  die('error 1');
 }
 $imageinfo = getimagesize($_FILES['my_files']['tmp_name']);
 if($imageinfo['mime'] != 'image/gif' && $imageinfo['mime'] != 'image/jpeg'&& $imageinfo['mime']      != 'image/jpg'&& $imageinfo['mime'] != 'image/png') {
   die('error 2');
 }
//check double file type (image with comment)
if(substr_count($filetype, '/')>1){
die('error 3')
}

 // upload to upload direcory 
 $uploaddir = 'upload/'.date("Y-m-d").'/' ;

if (file_exists($uploaddir)) {  
} else {  
    mkdir( $uploaddir, 0777);  
}  
  //change the image name
 $uploadfile = $uploaddir . md5(basename($_FILES['my_files']['name'])).$file_ext;



  if (move_uploaded_file($_FILES['my_files']['tmp_name'], $uploadfile)) {
 echo "<img id="upload_id" src="".$uploadfile.""><br />";
  } else {
   echo "error";
  }

Any new tips are welcome :)

 Answers

72

Re-process the image using GD (or Imagick) and save the processed image. All others are just fun boring for hackers.

Edit: And as rr pointed out, use move_uploaded_file() for any upload.

Late Edit: By the way, you'd want to be very restrictive about your upload folder. Those places are one of the dark corners where many exploits happen. This is valid for any type of upload and any programming language/server. Check https://www.owasp.org/index.php/Unrestricted_File_Upload

Wednesday, March 31, 2021
 
TecHunter
answered 7 Months ago
24

This is what I use, you can customize it to suit your script:

Simply change the *path and *variables.

<?php
// Configuration - Your Options
$allowed_filetypes = array('.mov','.mp3','.mp4','.flv'); // These will be the types of file that will pass the validation.
$max_filesize = 524288; // Maximum filesize in BYTES (currently 0.5MB).
$upload_path = './files/'; // The place the files will be uploaded to (currently a 'files' directory).

$filename = $_FILES['userfile']['name']; // Get the name of the file (including file extension).
$ext = substr($filename, strpos($filename,'.'), strlen($filename)-1); // Get the extension from the filename.

// Check if the filetype is allowed, if not DIE and inform the user.
if(!in_array($ext,$allowed_filetypes))
die('The file you attempted to upload is not allowed.');

// Now check the filesize, if it is too large then DIE and inform the user.
if(filesize($_FILES['userfile']['tmp_name']) > $max_filesize)
die('The file you attempted to upload is too large.');

// Check if we can upload to the specified path, if not DIE and inform the user.
if(!is_writable($upload_path))
die('You cannot upload to the specified directory, please CHMOD it to 777.');

// Upload the file to your specified path.
if(move_uploaded_file($_FILES['userfile']['tmp_name'],$upload_path . $filename))
echo 'Your file upload was successful, view the file <a href="' . $upload_path . $filename . '" title="Your File">here</a>'; // It worked.
else
echo 'There was an error during the file upload. Please try again.'; // It failed :(.

?>
Wednesday, March 31, 2021
 
relyt
answered 7 Months ago
66

First, you are missing a s3 'filename' aka key:

'Key' => '/files/imgage/fuzzykitten.jpg'

Next, I have had far fewer complications with:

//use AwsS3S3Client;
use AwsCommonEnumRegion;
//use AwsCommonAws;
use AwsS3EnumCannedAcl;
use AwsS3ExceptionS3Exception;
use GuzzleHttpEntityBody;


$amazon = AwsS3S3Client::factory($config)

with being able to find the class files. Every time I try to include ./common/aws or ./s3/s3client, it start giving me "cannot find AwsS3AwsS3Client" which leaves me at wt???

Wednesday, March 31, 2021
 
Saurabh
answered 7 Months ago
12

I recommend using jsupload plugin for this purpose. Your javascript would be:

$(document).ready(function() {
$("#uploadbutton").jsupload({ 
    action: "addFile.do",
    onComplete: function(response){
      alert( "server response: " + response);
    }   
});
Saturday, May 29, 2021
 
Evernoob
answered 5 Months ago
58

Some things I learned recently from a web security video:

  • The nuclear option is to serve all uploaded content from a separate domain which only serves static content - all features are disabled and nothing important is stored there.
  • Considering processing images through imagemagick etc. to strip out funny business.
  • For an example of what you are up against, look up GIFAR, a technique that puts a GIF and Java JAR in the same file.
Monday, August 2, 2021
 
Eduardo Sousa
answered 3 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :