Page 1 of 1

Uploading files

Posted: Sat Nov 01, 2008 2:22 pm
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???

Re: Uploading files

Posted: Sat Nov 01, 2008 3:08 pm
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.

Re: Uploading files

Posted: Sat Nov 01, 2008 3:14 pm
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>
??

Re: Uploading files

Posted: Sat Nov 01, 2008 4:01 pm
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.

Re: Uploading files

Posted: Sun Nov 02, 2008 1:36 pm
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.

Re: Uploading files

Posted: Sun Nov 02, 2008 4:18 pm
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?

Re: Uploading files

Posted: Fri Nov 07, 2008 11:33 am
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