phppup Posted March 14, 2021 Share Posted March 14, 2021 Secret doing some reading too educate myself, I am now more confused than before. LoL Trying to understand the most effective method to verify that an image is truly what is claimed. But the differences between using imagecreate, imagecreatefromjpeg, and is_uploaded_file are not easily noticed. Likewise, I read that it is best to check the image BEFORE uploading. But isn't the image already uploaded when submitted (although not yet moved or renamed)? Quote Link to comment https://forums.phpfreaks.com/topic/312294-verifying-an-image-is-an-image/ Share on other sites More sharing options...
Barand Posted March 14, 2021 Share Posted March 14, 2021 (edited) posted in error Edited March 14, 2021 by Barand senility Quote Link to comment https://forums.phpfreaks.com/topic/312294-verifying-an-image-is-an-image/#findComment-1585078 Share on other sites More sharing options...
requinix Posted March 14, 2021 Share Posted March 14, 2021 1 hour ago, phppup said: But the differences between using imagecreate, imagecreatefromjpeg, and is_uploaded_file are not easily noticed. imagecreate: Create a new image imagecreatefromjpeg: Load a JPEG from a file is_uploaded_file: Check that the file path given was truly from a file upload Very, very different. 1 hour ago, phppup said: Likewise, I read that it is best to check the image BEFORE uploading. But isn't the image already uploaded when submitted (although not yet moved or renamed)? If you can, yes. Saves the user from uploading a file that is going to be rejected. But you still have to verify it in PHP. For validation, examine with getimagesize. For sanitization, load the image into memory and resave it to file. Quote Link to comment https://forums.phpfreaks.com/topic/312294-verifying-an-image-is-an-image/#findComment-1585080 Share on other sites More sharing options...
phppup Posted March 14, 2021 Author Share Posted March 14, 2021 My confusion deepens. It seems as if imagecreate and imagecreatefromjpeg would be cousins, with ...from jpeg being more appropriate for validation. Am I correct in assuming that each extension needs is own ...createfromXYZ for accurate info? is_uploaded_file seems as if it's çlosing the barn after the horse has escaped. If it returns FALSE, but already has a tmpname, isn't the damage already underway? Does not working/moving the particular file "save the day"? So we're talking non-PHP coding to validate BEFORE upload (if I choose to be ultra user-friendly? I appreciate your help, but regarding getimagesuze, PHP.net has a CAUTIONARY note stating: Quote Do not use getimagesize() to check that a given file is a valid image. Use a purpose-built solution Thus, my confusion escalates. Quote Link to comment https://forums.phpfreaks.com/topic/312294-verifying-an-image-is-an-image/#findComment-1585081 Share on other sites More sharing options...
requinix Posted March 15, 2021 Share Posted March 15, 2021 37 minutes ago, phppup said: It seems as if imagecreate and imagecreatefromjpeg would be cousins, with ...from jpeg being more appropriate for validation. imagecreate creates a brand new image with nothing in it. I want you to spend the rest of the day thinking how that could help you validate an image file. imagecreatefromjpeg is great for loading an image file, but only when you know it's a JPEG. A more versatile function is imagecreatefromstring because it can detect the image type, but you have to load the file's contents into a string. Is there a "imagecreatefromfile" that's like imagecreatefromstring but works on files directly? No. Why not? 37 minutes ago, phppup said: Am I correct in assuming that each extension needs is own ...createfromXYZ for accurate info? See above. 37 minutes ago, phppup said: is_uploaded_file seems as if it's çlosing the barn after the horse has escaped. If it returns FALSE, but already has a tmpname, isn't the damage already underway? Does not working/moving the particular file "save the day"? That function is a safeguard to make sure you don't accidentally try to process a file somewhere on the server. If you throw in that check then you can be sure the filename is truly an uploaded file your script just received. 37 minutes ago, phppup said: So we're talking non-PHP coding to validate BEFORE upload (if I choose to be ultra user-friendly? Yes. 37 minutes ago, phppup said: I appreciate your help, but regarding getimagesuze, PHP.net has a CAUTIONARY note stating: Thus, my confusion escalates. It can guess at what type of image is contained in a file. It does not also then validate that the rest of the file is a valid image. For sufficiently small images, getimagesize to detect image type + imagecreatefrom(format) to load into memory + image(format) to save to a new location. Quote Link to comment https://forums.phpfreaks.com/topic/312294-verifying-an-image-is-an-image/#findComment-1585082 Share on other sites More sharing options...
phppup Posted March 15, 2021 Author Share Posted March 15, 2021 Quote Quote Is there a "imagecreatefromfile" that's like imagecreatefromstring but works on files directly? No. Why not? Because as long as you know the type of file your chasing, you can select the appropriate imagecreatefrom... command! (Not gonna ask what happens if you use the wrong one... LoL) Quote For sufficiently small images... I was planning to resize images AFTER the upload. So image size is an unknown. With that in mind, I will try to maximize the allowable file size, but I'm guessing even that has limitations (regardless of my intentions for the new file)? Quote Link to comment https://forums.phpfreaks.com/topic/312294-verifying-an-image-is-an-image/#findComment-1585083 Share on other sites More sharing options...
requinix Posted March 15, 2021 Share Posted March 15, 2021 1 hour ago, phppup said: Because as long as you know the type of file your chasing, you can select the appropriate imagecreatefrom... command! My point is that there is a function to load any supported image type from a string, so why not a function to load any supported image type from a file too? 1 hour ago, phppup said: (Not gonna ask what happens if you use the wrong one... LoL) Error message and no image. 1 hour ago, phppup said: I was planning to resize images AFTER the upload. So image size is an unknown. But there are still going to be guidelines. Or do you want to be able to support images up to many MBs in size? 1 hour ago, phppup said: With that in mind, I will try to maximize the allowable file size, but I'm guessing even that has limitations (regardless of my intentions for the new file)? The only limitations with limiting file size are the limitations on the file size. Not sure what you're getting at. One thing to remember is that loading an image into memory with functions like imagecreatefromjpeg will use a lot of memory. A 1MB file does not mean 1MB of memory. It means quite a bit more than that. So if you aren't careful, someone could upload a 10MB image and have your PHP script crash with OOM errors because it tried to use, I dunno, 200MB of memory to hold the image. Because the size of an image file does not correlate with the size of the image it contains: I can create a <100KB GIF file that is 10000x10000px in size, and if each pixel required a mere 10 bytes of memory to represent then that's 1GB of memory needed to load it. Quote Link to comment https://forums.phpfreaks.com/topic/312294-verifying-an-image-is-an-image/#findComment-1585085 Share on other sites More sharing options...
phppup Posted March 15, 2021 Author Share Posted March 15, 2021 (edited) Quote My point is that there is a function to load any supported image type from a string, so why not a function to load any supported image type from a file too? I'll take a stab at this and say that a string becomes somewhat universal, but a file has stricter parameters that dictate it's handling. I would also suspect that while the average user accepts whatever file is afforded, there are probably pros and cons from an artistic/ photo/ graphic perspective and different image file types offer quality and access benefits. Quote Because the size of an image file does not correlate with the size of the image it contains Would an enormous overload of memory generally be a maliciously inspired? Or simply a by-product of a particular image's content? Will resizing an image to a smaller file size automatically reduce it's maximum display size? It's color quality? Pixel saturation? I've not truly figured out what is being reduced and how the file is effected. So if an image file is stored in a db (not my intention, but I've seen many examples) is the file stored or is it translated into a string? Is the 'size' of a string generally smaller than the image file it supports? Edited March 15, 2021 by phppup Typos Quote Link to comment https://forums.phpfreaks.com/topic/312294-verifying-an-image-is-an-image/#findComment-1585086 Share on other sites More sharing options...
requinix Posted March 15, 2021 Share Posted March 15, 2021 3 minutes ago, phppup said: Would an enormous overload of memory generally be a maliciously inspired? Or simply a by-product of a particular image's content? Yes. 3 minutes ago, phppup said: Will resizing an image to a smaller file size automatically reduce it's maximum display size? It's color quality? Pixel saturation? I don't know what "maximum display size" is supposed to be, but reducing an image will always have some effect on the image depending on the image. 3 minutes ago, phppup said: So if an image file is stored in a db (not my intention, but I've seen many examples) is the file stored or is it translated into a string? Is the 'size' of a string generally smaller than the image file it supports? If you store the file in the database then the file is stored in the database. Whether it's a "string" or not is debatable but the answer is basically "yes". The size of a PHP string is exactly equal to the size of the file. Please, think about that question until you arrive at the same conclusion yourself. Quote Link to comment https://forums.phpfreaks.com/topic/312294-verifying-an-image-is-an-image/#findComment-1585087 Share on other sites More sharing options...
phppup Posted March 15, 2021 Author Share Posted March 15, 2021 (edited) Quote Would an enormous overload of memory generally be a maliciously inspired? Or simply a by-product of a particular image's content? Yes to both, huh? Interesting Quote string is exactly equal to the size of the file. Got it. I suppose every pixel is individually represented. I wasn't sure if the inner workings of an image allowed for coding that might say "each corner is black" or "top half is blue." A few lines of code can create miles of resulting data, but I guess an image file is more literal in it's formatting. Although there must be a differentiation somewhere down the line. A camera can be set to take the same photo at different file size or different quality settings (what's the best combination when trying to budget a memory card?) And yet, the same photograph will produce a different file size when created in raw, jpg, or others. But that's probably a different chapter. LOL Edited March 15, 2021 by phppup Typos Quote Link to comment https://forums.phpfreaks.com/topic/312294-verifying-an-image-is-an-image/#findComment-1585088 Share on other sites More sharing options...
requinix Posted March 15, 2021 Share Posted March 15, 2021 41 minutes ago, phppup said: I wasn't sure if the inner workings of an image allowed for coding that might say "each corner is black" or "top half is blue." Nope. At least not the typical image formats - I wouldn't be surprised if SVG could do that, but that's a special image format that doesn't work like the others. 41 minutes ago, phppup said: Although there must be a differentiation somewhere down the line. A camera can be set to take the same photo at different file size or different quality settings (what's the best combination when trying to budget a memory card?) And yet, the same photograph will produce a different file size when created in raw, jpg, or others. But that's probably a different chapter. LOL It's all about compression. Raw images aren't, JPEG images use algorithms that are very well suited to photographs but will lose some information to do that, PNG images compress in different ways that don't lose information, and so on. Quote Link to comment https://forums.phpfreaks.com/topic/312294-verifying-an-image-is-an-image/#findComment-1585089 Share on other sites More sharing options...
kicken Posted March 15, 2021 Share Posted March 15, 2021 40 minutes ago, phppup said: Although there must be a differentiation somewhere down the line. A camera can be set to take the same photo at different file size or different quality settings (what's the best combination when trying to budget a memory card?) And yet, the same photograph will produce a different file size when created in raw, jpg, or others. But that's probably a different chapter. LOL The size/quality variations come down to the different compression techniques and settings one uses. When the image is decompressed, which it will be when you load it with something like imagecreatefromXXX to do work on it (ie, resize it) then it will be using a certain amount of memory per-pixel so the image size in pixels will give you an idea of how much RAM you need to load it. A full color image for example may need 32-bits (4-bytes) per pixel when loaded into memory so a 1920x1080 image would need about 8MB of memory even though the compressed file size may only be a few hundred KB. Quote Link to comment https://forums.phpfreaks.com/topic/312294-verifying-an-image-is-an-image/#findComment-1585090 Share on other sites More sharing options...
phppup Posted March 15, 2021 Author Share Posted March 15, 2021 I've got the is_uploaded_file in place. Let's assume a user attempts to upload several images and the second file is an empty NOT-uploaded file. Is it safe to CONTINUE my loop and rename the other files? Or is it more advisable to BREAK the loop immediately. Getting back to my initial thread, for file authentication, what is the equivalent to imagecreatefromjpeg for a TIFF file? What's the best way to handle them to minimize vulnerability? Quote Link to comment https://forums.phpfreaks.com/topic/312294-verifying-an-image-is-an-image/#findComment-1585097 Share on other sites More sharing options...
requinix Posted March 15, 2021 Share Posted March 15, 2021 10 minutes ago, phppup said: Let's assume a user attempts to upload several images and the second file is an empty NOT-uploaded file. Impossible. The only way is_uploaded_file will return false is if you give it a file path for something that is not $_FILES[something]["tmp_name"]. Which, if it happens, is a sign that the code is very fundamentally broken. Quote Link to comment https://forums.phpfreaks.com/topic/312294-verifying-an-image-is-an-image/#findComment-1585099 Share on other sites More sharing options...
phppup Posted March 15, 2021 Author Share Posted March 15, 2021 Quote foreach ($_FILES['files']['tmp_name'] as $key => $value) { if( !empty($value) && is_uploaded_file( $value )){ //FILE is REAL return true; } } Is there a way to test it's functionality? Best way to ensure a TIFF is truly an image file? Quote Link to comment https://forums.phpfreaks.com/topic/312294-verifying-an-image-is-an-image/#findComment-1585110 Share on other sites More sharing options...
Psycho Posted March 15, 2021 Share Posted March 15, 2021 12 hours ago, phppup said: I suppose every pixel is individually represented. No. There are lossless and lossy image compression formats. Both use different methods of storing the data. A RAW image format is one form of lossless image format that has distinct data for every single pixel along with it's color. That is why they are huge in storage space. A gif and jpg (typically) are lossy formats (substitute some fidelity to create small file sizes) but work very differently. A gif has a color palet that can only hold 256 colors. It then defines each pixel in the gif by those colors. I suspect it does some other calculations such as define the pixel at index 1, 1 then also sets a repeat number. E.g. if the first 20 pixels are all the same color, it only has to define the color of the first pixel and then another value for the repeater. A JPG allows for 16 million colors but it does it's compression using more mathematical processes. For example, it may shift the color of a pixel slightly in order to make the compression more efficient. 17 hours ago, phppup said: Likewise, I read that it is best to check the image BEFORE uploading. But isn't the image already uploaded when submitted (although not yet moved or renamed)? What that really means is to verify the image before saving/using it. You can only do so much validation of the image before uploading it. Once it is initially uploaded to the $_FILES array, you an run whatever validations, modifications on them and THEN save them however you choose. I think the problem you are running into is that you are reading different bits and pieces of information, but not understanding the info or WHY you should do those things. It is possible to have a legitimate image that contains malicious code. And, depending on how you use the images on your site, you could potentially risk exposing your users. So, while you should be doing things to ensure what the user provided has a legitimate image extension and PHP can tell it is an image file, a best practice is to recreate the image to remove any potentially malicious content in the image. Here is an article that explains how these vulnerabilities exist: https://asdqwedev.medium.com/remote-image-upload-leads-to-rce-inject-malicious-code-to-php-gd-image-90e1e8b2aada Quote Link to comment https://forums.phpfreaks.com/topic/312294-verifying-an-image-is-an-image/#findComment-1585112 Share on other sites More sharing options...
phppup Posted March 15, 2021 Author Share Posted March 15, 2021 Thanks for clearing up a few things. Informative article, but didn't tell me how to prevent or handle an attack. Quote Link to comment https://forums.phpfreaks.com/topic/312294-verifying-an-image-is-an-image/#findComment-1585114 Share on other sites More sharing options...
Psycho Posted March 15, 2021 Share Posted March 15, 2021 Here is my suggestion: Limit the size of the images you will accept Do an initial check on the extension and MIME type of the file and refuse anything that is not what you expect Use getimagesize() to verify it is an image. Resize/recreate the image. This will remove some/most malicious code. Change the name of the image Set the folder(s) where you store the images so files cannot be executed Don't allow direct access to images. E.g. when displaying the images on a page use something like <image src="getimage.php?id=5"> and create the script getimage.php to find the image based on the id (or whatever parameters you define) and pass the image contents back to the browser to be displayed. This way the malicious user won't even know how to access the file he uploaded. Quote Link to comment https://forums.phpfreaks.com/topic/312294-verifying-an-image-is-an-image/#findComment-1585116 Share on other sites More sharing options...
phppup Posted March 15, 2021 Author Share Posted March 15, 2021 And I thought this was gonna be easy. LOL Is this a correct and effective use for security: Quote foreach ($_FILES['files']['tmp_name'] as $key => $value) { if( !empty($value) && is_uploaded_file( $value )){ //FILE is REAL return true; } } Does getimagesize() serve any purpose beyond obtaining the MIME type? How do I re-create a TIFF file? Quote Link to comment https://forums.phpfreaks.com/topic/312294-verifying-an-image-is-an-image/#findComment-1585118 Share on other sites More sharing options...
phppup Posted March 15, 2021 Author Share Posted March 15, 2021 Changed my code slightly, but still not getting a successful result Quote foreach ($_FILES['files']['tmp_name'] as $key => $value) { if( !empty($value) && is_uploaded_file( $value )){ //FILE is REAL echo "success"; } else { echo "false"; } Does is_uploaded_file merely confirm that the path described is the same path used? Does getimagesize() serve any purpose beyond obtaining the MIME type? How do I re-create a TIFF file? Quote Link to comment https://forums.phpfreaks.com/topic/312294-verifying-an-image-is-an-image/#findComment-1585122 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.