Re: A patch to keep cache directory out of webroot

Alla Bezroutchko <[email protected]> Thu, 07 Oct 2004 11:46:10 +0200
Newsgroups gmane.comp.cms.xaraya.patches
Organization Xaraya
Message-ID <[email protected]>
Jonn Beames wrote:
> I've reviewed the patch and it looks good.  However, I'm going to 
> propose that we address the problem identified by Alla another way, for 
> other reasons.  The patch has great value for identifying the problem 
> and what is required to fix it, but rather than applying it directly, I 
> think we should learn from it and make similar, but slightly different, 
> changes, as explained below...

I see that I have attacked a complex problem in a much too fearless way. 
   The dependencies are too complex for me to make a useful contribution 
to solving this problem. In any case, making the whole var directory 
movable is even better idea. As far as I am concerned, the more stuff 
goes out of webroot, the better.

Just to clarify the security problem. HTTP protocol supports PUT method. 
PUT method tells the server to upload and create a file. IIS supports 
this method by default (and it takes some pain to disable it). Apache 
only supports it if WebDAV module is enabled or if some other extension 
is specifically made to support it. So, suppose I have Apache server 
with WebDAV enabled:

------quoting httpd.conf-------
DocumentRoot "/var/www/htdocs-dav"
<Directory "/var/www/htdocs-dav">
         AllowOverride None
         Order allow,deny
         Allow from all

         DAV On
</Directory>
-----end quote-----

There I have an apache-writable directory in webroot:

% ls -ld /var/www/htdocs-dav/writable
drwxr-xr-x  3 apache  apache  512 Oct  7 11:11 /var/www/htdocs-dav/writable

Now I can upload files to it remotely.

Creating a local file:
--------------------------------------------------------
yeti:~$ cat > test.txt
Test test test...
^D
--------------------------------------------------------

Uploading local file to the remote server. -T switch tells curl to
send a PUT request with the file content in the body of the request.
--------------------------------------------------------
yeti:~$ curl -T test.txt http://test.example.com/writable/

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<HTML><HEAD>
<TITLE>201 Created</TITLE>
</HEAD><BODY>
<H1>Created</H1>
Resource /writable/test.txt has been created.</BODY></HTML>
100   200    0   182  100    18    654     64  0:00:00  0:00:00  0:00:00 
  1291
-----------------------------------------------------------

Now I can fetch my file from the remote server:
-----------------------------------------------------------
yeti:~$ curl http://test.example.com/writable/test.txt

Test test test...
-----------------------------------------------------------

Instead of a text file I can upload a PHP file, for example a PHP shell. 
So, writable directory gives anybody a shell access to the server with 
apache user privilege.

It works exactly the same on IIS.

An Apache web server with WebDAV enabled and no authentication required 
is probably quite a rare misconfiguration. On the other hand WebDAV is 
enabled by default in some Linux distros, and many hosting providers 
might enable it for their customers.

On IIS WebDAV is enabled by default, out of the box. Even worse, 
depending on the version of IIS the uploaded file might be executed as 
SYSTEM (root analog on Windows). So on IIS a writable directory in 
webroot might mean an direct way to compromise the system completely.

It is possible to avoid this problem on Apache by either disabling 
WebDAV, configuring access control lists or denying access to the 
directory through Apache config. On IIS it might be possible to work 
around it using something like urlscan tool from Microsoft. In any case, 
I suppose, this should be documented, so at least you can say "we told you".

Alla.