RE: [PHP-CVS] How to painlessly defuse the CGI exploit.
| From: | Preston L. Bannister | Date: | Tue, 14 May 2002 18:10:29 +0000 |
| Subject: | RE: [PHP-CVS] How to painlessly defuse the CGI exploit. | ||
| References: | 1 | Groups: | php.cvs |
| Request: | Send a blank email to php-cvs+get-11917@lists.php.net to get a copy of this message | ||
Let me try this one more time. I understand that James and Shane
are a little foggy - perhaps I can clarify :).
The first rule is that you do not *ever* place powerful general
purpose programs in /cgi-bin/. Even "cat" is too general purpose
to be safe and PHP far more powerful.
Pretty much everything else falls out of the first rule.
How do you make the first rule work while using CGI?
On Unix one simple and efficient solution is to make your scripts
executable in the conventional fashion:
#!/bin/php
<?php echo "Howdy!"; ?>
Given that most (all?) modern versions of Unix do the #! handling
inside the kernel, this is relatively efficient.
Individual web server implementations may offer other ways to map
scripts to interpreters.
On Windows under IIS you can use "Application Mappings" to invoke
PHP for particular file extensions. There is no need for the PHP
executable to reside in the web tree - and no CGI exploit.
On Windows under Apache you need a bit of indirection. Apparently
there is no way to match a script to an interpreter outside the set
of directories addressable under DOCUMENT_ROOT. So to make PHP safe
you restrict the way in which it can be called.
Place a "php.bat" in the Apache cgi-bin directory containing commands:
@echo off
c:\php\php.exe
The Apache configuration then becomes:
AddType application/x-httpd-php .php .phtml
Action application/x-httpd-php "/cgi-bin/php.bat"
This prevents PHP from receiving command line parameters, and thus
defeats the exploit.
This is *only* needed for web servers that cannot match up scripts to
interpreters outside DOCUMENT_ROOT.
The result is safe, easy to understand, and simpler for all involved.
The changes to PHP are very simple. Update the documentation to for
Apache on Windows to use the above setup. Remove the test that tries
(poorly) to detect if PHP were called safely.
It would be nice if there were some clean way to determine when the
PHP CGI usage was safe. Given that web server implementations vary
rather a lot, you'd have to introduce tests specific to each and every
web server implementation.
As a sanity check I took a look through the Perl code. The Perl folks
have been at this rather longer, and if a good solution was possible,
you'd expect to see a mention in the code or online.
Perl doesn't even look at the CGI environment.
From: James Cox [mailto:james@blog.at]
> Preston,
>
> I don't want to defuse your enthusiasm, but there are a number of points.
>
> firstly: this doesn't only apply to apache, it's just noticeable because of
> apache. There are thousands of web servers out there with different
> attitudes to CGI. The RFC for CGI states clearly how CGI is to be handled
> (via redirects, for security), and so the webservers that don't conform to
> this spec are invalid. Apache is one of them, but they choose to not change
> this behaviour.
>
> So, in the CGI SAPI, we choose to force redirects, and if no such process
> exists in the webserver, we have to implement one, by way of specifying
> redirect info.
>
> Yes.
>
> it doesn't make all that much sense. i know it's hard to comprehend, and
> believe me, it's harder to write and explain it. but from discussion with
> Shane, it just doesn't seem sensible to special case apache here.
>
> This functionality, albeit difficult and confusing, works.
>
> lets not change it again.
>
> James