Uploading files

Discussions of secure PHP coding. Security in software is important, so don't be afraid to ask. And when answering: be anal. Nitpick. No security vulnerability is too small.

Moderator: General Moderators

Post Reply
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Uploading files

Post by alex.barylski »

When you allow arbitrary files to be uploaded there is a security risk that someone uploads a PHP file and then executes the file by accessing it from a web browser. There are many ways to circumvent this issue (proxy scripts, etc).

In this case, the files are best stored in a publically accessible directory without a proxy...checking MIME types is not enough so what I'm thinking is...

Could I not just search and replace the opening tags with HTML comments of every file uploaded?

Code: Select all

str_replace(array('<?','<%'), '<!--', $subject);
My only concern is that files like PDF might use one of the matches for it's own purposes so maybe it's best to search for <?php and make sure the server only parses PHP files with full tags.

What directive (php.ini or apache.conf) is responsible for forcing such a policy and is this enough, assuming I only have PHP enabled and not anotherscripting language accessible from public interfaces???
User avatar
Syntac
Forum Contributor
Posts: 327
Joined: Sun Sep 14, 2008 7:59 pm

Re: Uploading files

Post by Syntac »

You could just prevent files with the .php extension from being uploaded. Any other extensions that are processed as PHP should also be blocked.
Hannes2k
Forum Contributor
Posts: 102
Joined: Fri Oct 24, 2008 12:22 pm

Re: Uploading files

Post by Hannes2k »

Hi,
and what happens if there is such a fragment in the uploaded file:

Code: Select all

 
<script language="php">
foreach($files_on_my_webspace AS $file) {
  unlink($file);
}
</script>
??
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: Uploading files

Post by alex.barylski »

Good point I forgot about that tag...

Although is it not possible to configure PHP to *only* parse <?php tags? I know you can disable short tags and/or ASP tags so I wonder if you can disable everything else and just allow <?php

I need to allow people to upload arbitrary files (including PHP)...I cannot store files outside of docroot and use a proxy either...I need to figure out a way to prevent execution so stripping the tags seemed most logical.

I can't store files outside of docroot because the files are accessed frequently so I decided early on to keep them accessible by apache directly -- and I also planned on allowing WebDAV access to these files, which I'm not sure would be possible storing them outside docroot.

I'm actually thinking now that perhaps a proxy script would work...hmmm...

I would need to store the proxy a few levels up and use .htaccess to deliver any requests to sub-directories to the proxy...

Code: Select all

proxy.php
.htaccess
/gallery/
/gallery/01/images/
/gallery/01/documents/ => Any files
Any request to files stored in anything under gallery would be channeled through proxy.php -- this should probably be asked in the Linux forum...

But still are there any security implications with the above, other than if .htaccess is configured wrong the files would be delivered and executed as is.
User avatar
Mordred
DevNet Resident
Posts: 1579
Joined: Sun Sep 03, 2006 5:19 am
Location: Sofia, Bulgaria

Re: Uploading files

Post by Mordred »

Hockey, I thought that you'd know better than to use home-cooked security solutions!
str_replace(), if used correctly, would unrecoverably damage the original file.
If used incorrectly (i.e. without loop, like in your example) it would damage the file and still leave a hole (Imagine this: <?p<?phphp)

Depending on how your server is set up there are different possibilities, but the safest bet would be on turning off the php engine for the upload folders (with .htaccess or with apache config files):

Code: Select all

php_value engine off
The only danger that remains with this setup is LFI - but it's easy to check for it. You can also mitigate it by hiding the real system paths with rewrite rules.

Another often overlooked problem is with allowing HTML uploads - these are XSSes par excellance!
A simple solution is to serve them as plaintext, but it falls in the blacklisting trap: you'll have to enumerate all possible extensions that all possible browsers may interpret as html, whereas the attacker has to find only one you missed :/

If your applicaton design allows it, I suggest forcing "Content-type: binary/octet-stream" and "Content-Disposition: attachment" for all files.
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: Uploading files

Post by alex.barylski »

I was waiting for your reply. :P

It's why I posted on here...just to make sure I covered my tracks, or not in this case. I didn't even think of str_replace caveat although I knew instinctually it wasn't a good solution. For one it would irrevocably break PHP scripts. Good call. :)

What I ultimately decided on was to use the proxy script to serve the file contents when accessed directly. I'm using lighttp so I believe it's a single config file that I need to specify the mod_rewrite rules in so I don't have to worry about missing a configuration step each account I create.

Can you see any explotable possibilities with this approach outside of misconfigured server letting people access files directly?
User avatar
Mordred
DevNet Resident
Posts: 1579
Joined: Sun Sep 03, 2006 5:19 am
Location: Sofia, Bulgaria

Re: Uploading files

Post by Mordred »

Can you see any explotable possibilities with this approach outside of misconfigured server letting people access files directly?
Speaking theoretically (I can't speak about practice without seeing code :) ), there is still the problem with persistent XSS.

Here's another variant: http://code.google.com/p/doctype/wiki/A ... dDownloads
Post Reply