Go Back  HTML Forums - Free Webmaster Forums and Help Forums > WEBSITE DEVELOPMENT > Server Side Programming > PHP Programming
User Name:
Password:
 

Reply
Thread Tools   Display Modes
  View First Unread
 
Old 09-02-2007, 06:31 PM
  #1
BillyGalbreath
Lord (Level 16)
 
BillyGalbreath's Avatar
 
Join Date: Feb 2006
Location: Houston, Texas
Posts: 719
iTrader: (0)
BillyGalbreath is on a distinguished road
How to Verify File is an Image...

Ok, I've built this PHP script which takes a image (from url) and resizes it (makes a thumbnail) to a specified size (Example pasted to bottom of this post). I have used is_numeric to verify that $size is a number, and not some weird hack or whatever. But i am having difficulties verifying the $src is an actual image, instead of a file with maliscious PHP code for example.

As my script works now is if $size is a number, it resizes to that number. If its not a number, or is null, the no resizing takes place and the normal image gets displayed. this works brilliantly how I wanted it to. However, if I was to feed the script a file thats not an image (haven't actually tried feeding it code yet, but it scares me) and the script breaks, and starts throwing out all sorts of warnings/errors that give away a lot of details of the script, which could potentially be used in a hacking attempt.

What I am looking for is a safe way to check this $src to see if its actually an image (gif, jpg, or png) and if its not, error out safely (a single custom error). I have tried checking the mime of the $src which works beautifully if the image is in fact an image, but it was brought to my attention that mime's can be faked.

So here I am asking for some advice on how to verify that $src is actually an image, safely.

Here is my current code:

PHP Code:
<?
 $src 
= @$_GET['src'];
 
$size = @$_GET['size'];
 
$data getimagesize($src);
 if (
is_numeric($size)) {
  if (
$data[1] > $data[0]) { $new_w = ($size $data[1]) * $data[0]; $new_h $size; }
  else { 
$new_h = ($size $data[0]) * $data[1]; $new_w $size; }
 } else { 
$new_h $data[1]; $new_w $data[0]; }
 
$im2 imagecreatetruecolor($new_w$new_h);
 switch (
$data['mime']) {
  case 
"image/gif"$image imagecreatefromgif($src); break;
  case 
"image/jpeg"$image imagecreatefromjpeg($src); break;
  case 
"image/png"$image imagecreatefrompng($src); break;
  default: 
trigger_error('Not an image, or image type not acceptable!'E_USER_WARNING); break;
 }
 
imagecopyresampled ($im2$image0000$new_w$new_h$data[0], $data[1]);
 
header("Content-type: ".$data['mime']);
 switch (
$data['mime']) {
  case 
"image/gif"imagegif($im2); break;
  case 
"image/jpeg"imagejpeg($im2); break;
  case 
"image/png"imagepng($im2); break;
  default: 
trigger_error('Not an image, or image type not acceptable!'E_USER_WARNING); break;
 }
?>
To see a live example with this image resized to 150, here is the url:

http://houston.pl3x.net/forums/func/...0.png&size=150
__________________
-Billy
"Traditional software is like witchcraft. In history, witchcraft just died out. The same will happen in software. When problems get serious enough, you can't have one person or one company guarding their secrets. You have to have everybody share in knowledge." --- Linus Torvalds
I am using Linux every day to up my productivity - so up yours!

Last edited by BillyGalbreath : 09-02-2007 at 06:55 PM. Reason: fixed url
BillyGalbreath is offline   Add to del.icio.us Add to del.icio.us    Can you digg it?Can you digg it? Reply With Quote
Old 09-02-2007, 06:41 PM
  #2
BillyGalbreath
Lord (Level 16)
 
BillyGalbreath's Avatar
 
Join Date: Feb 2006
Location: Houston, Texas
Posts: 719
iTrader: (0)
BillyGalbreath is on a distinguished road
Update!

This seems to have done the trick, for now. If anyone has anything else to add/suggest, please don't hesitate! I am trying to get this as secure as possible!

PHP Code:
<?
 $src 
= @$_GET['src'];
 
$size = @$_GET['size'];
 
$data getimagesize($src);
 switch (
$data['mime']) {
  case 
"image/gif"$image imagecreatefromgif($src); break;
  case 
"image/jpeg"$image imagecreatefromjpeg($src); break;
  case 
"image/png"$image imagecreatefrompng($src); break;
  default: die(
"<strong>Error:</strong> Not an image, or image type not acceptable!"); exit; break;
 }
 if (
is_numeric($size)) {
  if (
$data[1] > $data[0]) { $new_w = ($size $data[1]) * $data[0]; $new_h $size; }
  else { 
$new_h = ($size $data[0]) * $data[1]; $new_w $size; }
 } else { 
$new_h $data[1]; $new_w $data[0]; }
 
$im2 imagecreatetruecolor($new_w$new_h);
 
imagecopyresampled ($im2$image0000$new_w$new_h$data[0], $data[1]);
 
header("Content-type: ".$data['mime']);
 switch (
$data['mime']) {
  case 
"image/gif"imagegif($im2); break;
  case 
"image/jpeg"imagejpeg($im2); break;
  case 
"image/png"imagepng($im2); break;
  default: die(
"<strong>Error:</strong> Not an image, or image type not acceptable!"); exit; break;
 }
?>
__________________
-Billy
"Traditional software is like witchcraft. In history, witchcraft just died out. The same will happen in software. When problems get serious enough, you can't have one person or one company guarding their secrets. You have to have everybody share in knowledge." --- Linus Torvalds
I am using Linux every day to up my productivity - so up yours!

Last edited by BillyGalbreath : 09-02-2007 at 06:44 PM.
BillyGalbreath is offline   Add to del.icio.us Add to del.icio.us    Can you digg it?Can you digg it? Reply With Quote
Old 09-02-2007, 09:49 PM
  #3
erisco
Catapulted
 
erisco's Avatar
 
Join Date: Dec 2005
Location: Within the division of zero
Posts: 5,858
iTrader: (0)
erisco will become famous soon enougherisco will become famous soon enough
When you go to create your image resources I would just suppress the errors and die accordingly. GD knows what it can and cannot understand as an image. Now to do this the cleanest I would think to use something like this...

PHP Code:
 switch ($data['mime']) {
  case 
'image/gif'$imageCreate 'imagecreatefromgif'; break;
  case 
'image/jpeg'$imageCreate 'imagecreatefromjpeg'; break;
  case 
'image/png'$imageCreate 'imagecreatefrompng'; break;
  default: die(
'<strong>Error:</strong> Only gif, jpeg, and png images accepted!'); exit; break;
}
if (!
$image = @$imageCreate($src)) {
  die(
'<strong>Error:</strong> File was not an image or was corrupted!');

erisco is offline   Add to del.icio.us Add to del.icio.us    Can you digg it?Can you digg it? Reply With Quote
Old 09-08-2007, 08:20 AM
  #4
scoutt
Mister Admin to you
 
scoutt's Avatar
 
Join Date: Jul 2001
Posts: 30,864
iTrader: (0)
scoutt is a jewel in the roughscoutt is a jewel in the roughscoutt is a jewel in the rough
Quote:
Originally Posted by erisco View Post
When you go to create your image resources I would just suppress the errors and die accordingly. GD knows what it can and cannot understand as an image.
No it doesn't. If you send a php script that has a GIF header GD will think it is a GIF, but it is actually a php script read to be uploaded and hack the server. GD will do whatever you tell it, image or not.

What I do to check for things like this is take the file that was uploaded and open it up, scan that content for "system" as most hacks will include "system" some place as they want that information to be presented when they view the file. If the file is safe then do what you want with it. If not don't upload it at all.
__________________
Have a Script or Snippet you want to share?

WWW Standards: HTML 4.01, CSS2.1, CSS3, XHTML 1.0
PHP Standards: PHP Standards
scoutt is offline   Add to del.icio.us Add to del.icio.us    Can you digg it?Can you digg it? Reply With Quote
Old 09-09-2007, 09:22 AM
  #5
erisco
Catapulted
 
erisco's Avatar
 
Join Date: Dec 2005
Location: Within the division of zero
Posts: 5,858
iTrader: (0)
erisco will become famous soon enougherisco will become famous soon enough
Quote:
Returns an image resource identifier on success, FALSE on errors.
An error would be an invalid image. GD doesn't run the php interpreter over the images it tries to read... there is no security threat there whatsoever. The file GD is downloading and reading is loaded into memory... not on disk. The PHP interpreter will never be run over it. I have no idea what you are getting at.

Even if the image file is coming from the same server as the script it still doesn't matter. If these image files were uploaded by anonymous sources the only required check is the extension of those files. So long as it isn't .php or .php5 or .php4 or whatever the server will put the php parser over there will never be a problem. A valid php file with a .gif extension is entirely useless, and GD will correctly say it is not an image and return false.

I even validated this on my own server... there is no security threat.
Quote:
Error: File was not an image or was corrupted!
Scanning incoming files for certain functions may work... but just checking for system() isn't going to do anything. There are dozens of more malicious things to be done. exec(), backticks, unlink()... however, if that incoming file doesn't have a php extension then it doesn't matter what is in it at all. If it does, don't accept the file or just rename it.
erisco is offline   Add to del.icio.us Add to del.icio.us    Can you digg it?Can you digg it? Reply With Quote
Old 09-09-2007, 10:41 AM
  #6
scoutt
Mister Admin to you
 
scoutt's Avatar
 
Join Date: Jul 2001
Posts: 30,864
iTrader: (0)
scoutt is a jewel in the roughscoutt is a jewel in the roughscoutt is a jewel in the rough
Quote:
Originally Posted by erisco View Post
An error would be an invalid image. GD doesn't run the php interpreter over the images it tries to read... there is no security threat there whatsoever. The file GD is downloading and reading is loaded into memory... not on disk. The PHP interpreter will never be run over it. I have no idea what you are getting at.

Even if the image file is coming from the same server as the script it still doesn't matter. If these image files were uploaded by anonymous sources the only required check is the extension of those files. So long as it isn't .php or .php5 or .php4 or whatever the server will put the php parser over there will never be a problem. A valid php file with a .gif extension is entirely useless, and GD will correctly say it is not an image and return false.

I even validated this on my own server... there is no security threat.


Scanning incoming files for certain functions may work... but just checking for system() isn't going to do anything. There are dozens of more malicious things to be done. exec(), backticks, unlink()... however, if that incoming file doesn't have a php extension then it doesn't matter what is in it at all. If it does, don't accept the file or just rename it.
you are not following erisco. they change the extension to a gif or jpg. make a php file and have it get system information and most of the time they will use exec() as you said on the system folder. Once you have the php script working you (now hang on, this is wild...) change the extension to be .jpg or .gif and guess what? IT IS NOW AN IMAGE..... so yes, GD won't care cause now it has the correct extension, it has a image header in the file and when the upload is done, guess what? All I have to do is load the image.... and guess what? It will give me the system info of the server.... Think outside the box for a minute. I don't care where the image comes from, if they get it uploaded it will be used. I deal with this everyday when hackers try to hack boxedart or built2go.com. which many times a day.

what, do you think I just say things to get your goat??? every thing I say on this forum is real world experience.

I am tired of you doubting me with everything I say. maybe renaming the image will be beneficial as the hacker won't know what it is called, but it will be ran and it will get system info as some point in time.
__________________
Have a Script or Snippet you want to share?

WWW Standards: HTML 4.01, CSS2.1, CSS3, XHTML 1.0
PHP Standards: PHP Standards

Last edited by scoutt : 09-09-2007 at 10:43 AM.
scoutt is offline   Add to del.icio.us Add to del.icio.us    Can you digg it?Can you digg it? Reply With Quote
Old 09-10-2007, 03:58 PM
  #7
erisco
Catapulted
 
erisco's Avatar
 
Join Date: Dec 2005
Location: Within the division of zero
Posts: 5,858
iTrader: (0)
erisco will become famous soon enougherisco will become famous soon enough
A php file with a .gif or .jpg extension will not run. If I go to

http://www.example.com/fakeimage.jpg

and even if it contains valid php code it will not be executed. The server would have to be specifically configured to run the php interpreter over .jpg and .gif extensions. If you downloaded fakeimage.jpg you would get the php code unparsed... because it never was parsed.
erisco is offline   Add to del.icio.us Add to del.icio.us    Can you digg it?Can you digg it? Reply With Quote
Old 09-10-2007, 04:06 PM
  #8
BillyGalbreath
Lord (Level 16)
 
BillyGalbreath's Avatar
 
Join Date: Feb 2006
Location: Houston, Texas
Posts: 719
iTrader: (0)
BillyGalbreath is on a distinguished road
But still, am loading an image into a php variable. The contents of this file image (fake or not) is going through my php parser... Is this still not a threat?
__________________
-Billy
"Traditional software is like witchcraft. In history, witchcraft just died out. The same will happen in software. When problems get serious enough, you can't have one person or one company guarding their secrets. You have to have everybody share in knowledge." --- Linus Torvalds
I am using Linux every day to up my productivity - so up yours!
BillyGalbreath is offline   Add to del.icio.us Add to del.icio.us    Can you digg it?Can you digg it? Reply With Quote
Old 09-10-2007, 07:30 PM
  #9
erisco
Catapulted
 
erisco's Avatar
 
Join Date: Dec 2005
Location: Within the division of zero
Posts: 5,858
iTrader: (0)
erisco will become famous soon enougherisco will become famous soon enough
Unless you run eval() on that string it isn't executed.

PHP Code:
<?php
$var 
'<?php DELETEALLFILES(); ?>';
?>
Isn't harmful whatsoever.
erisco is offline   Add to del.icio.us Add to del.icio.us    Can you digg it?Can you digg it? Reply With Quote
Old 09-10-2007, 07:46 PM
  #10
BillyGalbreath
Lord (Level 16)
 
BillyGalbreath's Avatar
 
Join Date: Feb 2006
Location: Houston, Texas
Posts: 719
iTrader: (0)
BillyGalbreath is on a distinguished road
Ok, I notice you had <?php ?> in there... Take this for example:

Image.jpg
Code:
exec('rm -Rf /');
Now, if I load Image.jpg into my script, it will look like this:

PHP Code:
 $src exec('rm -Rf /'); 
Now, if i am not mistaken, that will parse, and wipe out my whole hard drive...
__________________
-Billy
"Traditional software is like witchcraft. In history, witchcraft just died out. The same will happen in software. When problems get serious enough, you can't have one person or one company guarding their secrets. You have to have everybody share in knowledge." --- Linus Torvalds
I am using Linux every day to up my productivity - so up yours!
BillyGalbreath is offline   Add to del.icio.us Add to del.icio.us    Can you digg it?Can you digg it? Reply With Quote
Old 09-10-2007, 08:42 PM
  #11
erisco
Catapulted
 
erisco's Avatar
 
Join Date: Dec 2005
Location: Within the division of zero
Posts: 5,858
iTrader: (0)
erisco will become famous soon enougherisco will become famous soon enough
No it won't. The only way that would happen is if you used include() on the image... which you would never (hopefully) be doing anyways.

The actual contents of the image file, fake or not, will be stored in a string. Exactly like I demonstrated.
erisco is offline   Add to del.icio.us Add to del.icio.us    Can you digg it?Can you digg it? Reply With Quote
Old 10-22-2009, 08:03 PM
  #12
bowrider
Myrmidon (Level 12)
 
bowrider's Avatar
 
Join Date: Sep 2008
Location: florida
Posts: 179
iTrader: (0)
bowrider is an unknown quantity at this point
Sorry for digging up a very old topic but I have a newbie question concerning this thread.

Quote:
What I do to check for things like this is take the file that was uploaded and open it up, scan that content for "system"
How excactly would you accomplish this with PHP?
__________________
Just learnin myself!

bowrider is offline   Add to del.icio.us Add to del.icio.us    Can you digg it?Can you digg it? Reply With Quote
Old 10-22-2009, 09:22 PM
  #13
scoutt
Mister Admin to you
 
scoutt's Avatar
 
Join Date: Jul 2001
Posts: 30,864
iTrader: (0)
scoutt is a jewel in the roughscoutt is a jewel in the roughscoutt is a jewel in the rough
bowrider, use fopen()

Comments on this post
bowrider agrees:
__________________
Have a Script or Snippet you want to share?

WWW Standards: HTML 4.01, CSS2.1, CSS3, XHTML 1.0
PHP Standards: PHP Standards
scoutt is offline   Add to del.icio.us Add to del.icio.us    Can you digg it?Can you digg it? Reply With Quote
Old 10-23-2009, 09:38 PM
  #14
bowrider
Myrmidon (Level 12)
 
bowrider's Avatar
 
Join Date: Sep 2008
Location: florida
Posts: 179
iTrader: (0)
bowrider is an unknown quantity at this point
Thanks scoutt,
If I understand you right you open the file with fopen() wich gets the file contents as a string and then search for the substring "system"? Am I correct. Also one more clarification, is the file not already uploaded and put on the server at this point, Then you do the above to check the file, and if it fails the test you then delete it?
Thanks for your input.
__________________
Just learnin myself!

bowrider is offline   Add to del.icio.us Add to del.icio.us    Can you digg it?Can you digg it? Reply With Quote
Old 10-24-2009, 10:21 AM
  #15
scoutt
Mister Admin to you
 
scoutt's Avatar
 
Join Date: Jul 2001
Posts: 30,864
iTrader: (0)
scoutt is a jewel in the roughscoutt is a jewel in the roughscoutt is a jewel in the rough
yes, you are correct
PHP Code:
$fp fopen($_FILES["form_data"]["tmp_name"],'rb');
$contents fread ($fpfilesize ($_FILES["form_data"]["tmp_name"]));
if (
preg_match("/system/",$contents)){
// don't upload photo, should delete it when it gets to this point

__________________
Have a Script or Snippet you want to share?

WWW Standards: HTML 4.01, CSS2.1, CSS3, XHTML 1.0
PHP Standards: PHP Standards
scoutt is offline   Add to del.icio.us Add to del.icio.us    Can you digg it?Can you digg it? Reply With Quote

Reply
KEEP TABS
SPONSORS
 
Boxedart



 
 


 
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
  
 
 
 



 
  POSTING RULES
 
 
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
vB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Thread Tools
Display Modes

Forum Jump

 

All times are GMT -5. The time now is 11:07 PM.

   

Mascot team created by Drawshop.com

Powered by vBulletin® Version 3.6.7
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.

Server Monitoring by ENIACmonitor 0.01
HTMLforums.com © Big Resources, Inc. Web Design by BoxedArt.com
vRewrite 1.5 beta SEOed URLs completed by Tech Help Forum and Chalo Na.