doubledee Posted February 13, 2012 Share Posted February 13, 2012 Not sure if I used the right title?! This question is based on some other threads about uploading User Pictures to my website. Questions: 1.) If there is a file which is actually a photograph, but it is named "SomePhoto.xls" then what will happen? 2.) If there is a file which is actually a PHP script, but it is named "AnotherPhoto.jpg" then what will happen? 3.) If there is a file which is actually a Spreadsheet, but it is named "YetAnotherPhoto.png" then what will happen? In other words, what is the "driving" factor here... The file's true contents OR simply the file's name and extension? Thanks, Debbie Quote Link to comment Share on other sites More sharing options...
litebearer Posted February 13, 2012 Share Posted February 13, 2012 Did you try 1 & 3? Have you created a small test script for uploading images? Quote Link to comment Share on other sites More sharing options...
doubledee Posted February 13, 2012 Author Share Posted February 13, 2012 Did you try 1 & 3? I got a naked picture of Justin Bieber... What should I do?? Um, I asked because last night I had a file with PHP inside of it and yet labeled as an image (i.e. "test.php.jpg") and it ran as PHP... Have you created a small test script for uploading images? I'm working on it slowly if I can get some help here... It has been implied by others that I just rename any uploaded files, but I am wondering what would happen if a "bad" file slipped through my code checks and I renamed it from "really_an_evil_exe.jpg" to "1234.jpg" and then opened it later?! Here is what I have so far to check if a file is "valid", but I'm not sure how reliable my code is... // Determine if Photo was uploaded via HTTP POST. if (is_uploaded_file($_FILES['userPhoto']['tmp_name'])){ // File uploaded via HTTP. // Check File Type. if ($_FILES["userPhoto"]["type"] !== 'image/gif' && $_FILES["userPhoto"]["type"] !== 'image/jpeg' && $_FILES["userPhoto"]["type"] !== 'image/png'){ // Not Image File. $errors['upload'] = 'File-type must be either GIF, JPG, or PNG'; }else{ // Valid Image File. // Continue processing... } }else{ // Invalid upload method. $errors['upload'] = 'Invalid upload. Try again.'; } Not sure how "hackable" this could be? Debbie Quote Link to comment Share on other sites More sharing options...
kicken Posted February 13, 2012 Share Posted February 13, 2012 In other words, what is the "driving" factor here... The file's true contents OR simply the file's name and extension? There isn't really any single factor, however most software uses the extension as the determining factor. For instance when you upload your excel document that is named 'somefile.jpg' the browser will likely report it as a image/jpeg type. Some software will actually attempt to guess the mime type by examining the contents of the file. For example, IE does this I believe. PHP's getimagesize will do it to some extent and there is a library out there people can use to do this. It looks for special marks that exist only in certain formats in the contents of the file. Um, I asked because last night I had a file with PHP inside of it and yet labeled as an image (i.e. "test.php.jpg") and it ran as PHP... This is because apache takes into account all the extensions when deciding what to do with a file. "test.php.jpg" has two extensions: .jpg which tells apache it is an image/jpg file (the mime type) and .php which tells apache it needs to be processed using the php handler. Most software is only concerned with the right-most extension, in this case .jpg, and would treat it as an image. It has been implied by others that I just rename any uploaded files, but I am wondering what would happen if a "bad" file slipped through my code checks and I renamed it from "really_an_evil_exe.jpg" to "1234.jpg" and then opened it later?! Not sure how "hackable" this could be? It look ok so far. I would recommend not checking the $_FILES['userPhoto']['type'] key and instead check the results of calling getimagesize() on the file. The type set in that key is whatever the browser sent which could be a number of things. For instance, I've seen a JPEG image report as any of: image/jpeg image/jpg image/p-jpeg image/p-jpg getimagesize will provide a more reliable test because it actually checks the file's content not the extension. Quote Link to comment Share on other sites More sharing options...
litebearer Posted February 13, 2012 Share Posted February 13, 2012 Here is a quick test I did (2 mins).. created a file <?PHP echo "Hello World!"; ?> named it helloworld.jpg uploaded it to my wbesite pointed my browser to it the result - http://www.nstoia.com/helloworld.jpg Quote Link to comment Share on other sites More sharing options...
doubledee Posted February 13, 2012 Author Share Posted February 13, 2012 In other words, what is the "driving" factor here... The file's true contents OR simply the file's name and extension? There isn't really any single factor, however most software uses the extension as the determining factor. For instance when you upload your excel document that is named 'somefile.jpg' the browser will likely report it as a image/jpeg type. Some software will actually attempt to guess the mime type by examining the contents of the file. For example, IE does this I believe. PHP's getimagesize will do it to some extent and there is a library out there people can use to do this. It looks for special marks that exist only in certain formats in the contents of the file. So it is not enough to just check the File Extension of a file that a User uploaded, right? Is this code enough to determine the true contents of an Uploaded File... // Check File Type. if ($_FILES["userPhoto"]["type"] !== 'image/gif' && $_FILES["userPhoto"]["type"] !== 'image/jpeg' && $_FILES["userPhoto"]["type"] !== 'image/png'){ // Not Image File. $errors['upload'] = 'File-type must be either GIF, JPG, or PNG'; // $errors['upload'] = 'File-Type must be either gif, jpg, or png'; }else{ // Valid Image File. // Continue processing... } Um, I asked because last night I had a file with PHP inside of it and yet labeled as an image (i.e. "test.php.jpg") and it ran as PHP... This is because apache takes into account all the extensions when deciding what to do with a file. "test.php.jpg" has two extensions: .jpg which tells apache it is an image/jpg file (the mime type) and .php which tells apache it needs to be processed using the php handler. Most software is only concerned with the right-most extension, in this case .jpg, and would treat it as an image. That is what I would have guessed too. Apparently Apache is more aggressive and looks at all apparent extensions in the file name? Does Apache also inspect the File Contents in order to decide which Handler to launch? It has been implied by others that I just rename any uploaded files, but I am wondering what would happen if a "bad" file slipped through my code checks and I renamed it from "really_an_evil_exe.jpg" to "1234.jpg" and then opened it later?! Not sure how "hackable" this could be? It look ok so far. I would recommend not checking the $_FILES['userPhoto']['type'] key and instead check the results of calling getimagesize() on the file. The type set in that key is whatever the browser sent which could be a number of things. For instance, I've seen a JPEG image report as any of: image/jpeg image/jpg image/p-jpeg image/p-jpg getimagesize will provide a more reliable test because it actually checks the file's content not the extension. Should I do both or just skip to getImageSize()?? Also, I thought I read some places that getImageSize() can be tricked? Thoughts? Thanks, Debbie Quote Link to comment Share on other sites More sharing options...
doubledee Posted February 13, 2012 Author Share Posted February 13, 2012 Here is a quick test I did (2 mins).. created a file <?PHP echo "Hello World!"; ?> named it helloworld.jpg uploaded it to my wbesite pointed my browser to it the result - http://www.nstoia.com/helloworld.jpg I asked because I cannot test or know all outcomes. I created a test.jpg file with the contents "This is some PHP code" (10 seconds) and got different outcomes between Preview on my Mac and opening it and on my website. And FYI, I spent2-3 weeks building and TESTING my User Accounts module all by my lonesome, so, yes, I do know how to try things out myself. I also know when I should ask for help. And you also don't seem to understand that I get lonely and just like talking to others also... Debbie Quote Link to comment Share on other sites More sharing options...
kicken Posted February 13, 2012 Share Posted February 13, 2012 Apparently Apache is more aggressive and looks at all apparent extensions in the file name? It looks at each extension because each extension can provide different information. For example you could do something like: index.php.html.en and apache would deduce from the extensions that: - It's a text/html mime type - It needs run through the PHP handler - It's in the english language. Multiple extensions aren't really all that useful when dealing with a dynamic page such as a php page though, so it's better to configure the server to only use php if the final extension is .php. Some servers are not configured in this manner though so it opens up issues. Does Apache also inspect the File Contents in order to decide which Handler to launch? No, only the extensions. Should I do both or just skip to getImageSize()?? As I already said: I would recommend not checking the $_FILES['userPhoto']['type'] key Also, I thought I read some places that getImageSize() can be tricked? No, getimagesize will ensure it is a valid image, and it will tell you what type it is (jpeg, gif, or png). What it won't do is prevent someone from inserting PHP into the image in such a way that the image remains valid. Such as in the meta-data fields. That is why you take the extra step of making sure the code wont execute if someone does put it in there. Unrelated Side note: you should use the preview option before posting and make sure you get all your quote's correct. It makes it harder to read and understand your posts when you have people's quoted text mixed in with your own because the tags are messed up. Quote Link to comment Share on other sites More sharing options...
doubledee Posted February 13, 2012 Author Share Posted February 13, 2012 Kicken, I am reading up on getImageSize() now... ------ Unrelated Side note: you should use the preview option before posting and make sure you get all your quote's correct. It makes it harder to read and understand your posts when you have people's quoted text mixed in with your own because the tags are messed up. I almost always do. Why, where did I mess up? My last few posts look okay? Link to poorly formatted post? Thanks for everyone's help so far!! Debbie Quote Link to comment Share on other sites More sharing options...
requinix Posted February 13, 2012 Share Posted February 13, 2012 One thing that hasn't been pointed out yet: $_FILES[foo]["type"] is not secure because it is provided by the browser, not by PHP. You need to figure the type out by yourself (like with getimagesize()). Quote Link to comment Share on other sites More sharing options...
doubledee Posted February 13, 2012 Author Share Posted February 13, 2012 One thing that hasn't been pointed out yet: $_FILES[foo]["type"] is not secure because it is provided by the browser, not by PHP. You need to figure the type out by yourself (like with getimagesize()). Actually kicken mentioned that earlier.. I would recommend not checking the $_FILES['userPhoto']['type'] key and instead check the results of calling getimagesize() on the file. The type set in that key is whatever the browser sent which could be a number of things. For instance, I've seen a JPEG image report as any of: image/jpeg image/jpg image/p-jpeg image/p-jpg Since you bring it up again, though, maybe you can help me figure things out... I am unclear of how to access the getImageSize array?! First off, when I look in the manual it is strange the indices they use on the array. The manual says... Returns an array with 7 elements. Index 0 and 1 contains respectively the width and the height of the image. Note: Some formats may contain no image or may contain multiple images. In these cases, getimagesize() might not be able to properly determine the image size. getimagesize() will return zero for width and height in these cases. Index 2 is one of the IMAGETYPE_XXX constants indicating the type of the image. Index 3 is a text string with the correct height="yyy" width="xxx" string that can be used directly in an IMG tag. mime is the correspondant MIME type of the image. This information can be used to deliver images with the correct HTTP Content-type header: However, var_dump() says this... array 0 => int 1090 1 => int 530 2 => int 3 3 => string 'width="1090" height="530"' (length=25) 'bits' => int 8 'mime' => string 'image/png' (length=9) I would expect that the Image's Type is on position [2]. Also, I would expect [ 0 ] through [7]... What is up with that?! Debbie Quote Link to comment Share on other sites More sharing options...
PaulRyan Posted February 13, 2012 Share Posted February 13, 2012 Using list would do the trick: list($width, $height, $type) = getimagesize($_FILES['userPhoto']['tmp_name']); That is how I do it anyhow Regards, PaulRyan. Quote Link to comment Share on other sites More sharing options...
litebearer Posted February 13, 2012 Share Posted February 13, 2012 Might also look here... http://www.php.net/manual/en/function.exif-imagetype.php Quote Link to comment Share on other sites More sharing options...
doubledee Posted February 14, 2012 Author Share Posted February 14, 2012 Using list would do the trick: list($width, $height, $type) = getimagesize($_FILES['userPhoto']['tmp_name']); That is how I do it anyhow Regards, PaulRyan. Except if you look at my var_dump() above I get this... array 0 => int 1179 1 => int 525 2 => int 3 3 => string 'width="1179" height="525"' (length=25) 'bits' => int 8 'mime' => string 'image/png' (length=9) I would expect this... array 2 => 'image/png' Also, why is it if I select my "test.php.jpg" file, I get this error... Notice: getimagesize() [function.getimagesize]: Read error! in /Users/user1/Documents/DEV/++htdocs/05_Debbie/members/upload.php on line 56 Here is a snippet of my code... $tempName = $_FILES['userPhoto']['tmp_name']; // Determine if Image was uploaded via HTTP POST. if (is_uploaded_file($tempName)){ // File uploaded via HTTP. // Get of Image Details. $imageDetails = getImageSize($tempName); // Get Image Type $imageType = $imageDetails['mime']; echo '<p>var_dump($imageDetails) = ' . var_dump($imageDetails) . '</p>'; echo '<p>var_dump($imageType) = ' . var_dump($imageType) . '</p>'; Where Line 56 starts here: $imageDetails = getImageSize($tempName); (The var_dump() shows boolean false below the error message, but that shouldn't break anything?!) Debbie Quote Link to comment Share on other sites More sharing options...
scootstah Posted February 14, 2012 Share Posted February 14, 2012 Because it's not an image, so it returns false. Quote Link to comment Share on other sites More sharing options...
doubledee Posted February 14, 2012 Author Share Posted February 14, 2012 Because it's not an image, so it returns false. But that's circular logic I've been told to use... I am using getImageSize() to determine what TYPE the File is, and if this function pukes when it is not an Image then how am I supposed to know it is not an Image?! (I was under the impression that the function returned FALSE if it was not an Image.) So what is the solution?? I need a function that tells me the File Type including if it is NOT an Image. Any suggestions? Debbie Quote Link to comment Share on other sites More sharing options...
scootstah Posted February 14, 2012 Share Posted February 14, 2012 Oops, guess I skipped over the error. Check the folder permissions. Quote Link to comment Share on other sites More sharing options...
doubledee Posted February 14, 2012 Author Share Posted February 14, 2012 Oops, guess I skipped over the error. Check the folder permissions. How do I do that locally on MAMP? And how would I change them if they are wrong? Can I use TextWrangler? Debbie Quote Link to comment Share on other sites More sharing options...
Psycho Posted February 14, 2012 Share Posted February 14, 2012 I would expect this... array 2 => 'image/png' From the manual for getimagesize() under Return Values Index 2 is one of the IMAGETYPE_XXX constants indicating the type of the image. See the related function exif_imagetype() which lists the numeric number associated with each type (3 == PNG image) Also, why is it if I select my "test.php.jpg" file, I get this error... Notice: getimagesize() [function.getimagesize]: Read error! in /Users/user1/Documents/DEV/++htdocs/05_Debbie/members/upload.php on line 56 Again from the manual for getimagesize(), this time under Errors/Exceptions If accessing the filename image is impossible, or if it isn't a valid picture, getimagesize() will generate an error of level E_WARNING. On read error, getimagesize() will generate an error of level E_NOTICE. Although your problem may be a folder issue - the function can and will return errors if you don't pass it an image. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.