PHP security from the inside
Stefan Esser gets set for the month of PHP bugs
Why did you resign from the PHP Security Response Team?
Stefan Esser: First of all I did not suddenly resign, the response team knew I was very unhappy with the way things were dealt with, and I questioned the sense of the Security Response Team several times before I actually left. I resigned from the team for many reasons. First, I dislike the ways bugs are handled:
- Fixes get committed to public CVS (sometimes even quickly) => so that everyone can see them.
- It usually takes weeks or months until the next release [to fix the bug].
- No security updates [are released], only complete new releases (minor PHP revisions quite often break some functionality, usually by mistake).
- No test cases for fixed security bugs.
- Sometimes the fix is not working correctly (for example, when running on 64-bit systems).
- Bug gets reintroduced later.
- Bugfixes are often done sloppily.
- Sometimes it fixes only the symptoms (the same thing stays exploitable through other paths).
- Bugfixing code introduces new security holes.
- No information policy => if a bug was found by another developer, you will never see more than a single line of problem description anywhere.
Secondly, during the last year I was quite often called an immoral traitor or other things from PHP (core) developers for disclosing security holes in PHP to the public. One does not feel like a team member when the PHP Security Team/PHP Group has nothing more to say about this than: "Well that is your problem, not ours".
And the third point is that I strongly disagree with some of the members of the team about the definition of a security expert. My personal opinion is that there are far too many people out there that call themselves Web Applicaton/PHP security experts and write books/give talks about PHP Security, while they only know basic XSS and SQL Injection stuff (actually when you look at various PHP Security Talks you will often see nothing PHP-specific in them, with the possible exception of remote URL includes).
Browsing the changelog I see fixes for segfaults, memory leaks, and problems with missing checks. Maybe some of these bugs could be exploitable, but they will surely stop some scripts from working reliably. I am wondering how is it possible that a big project such as PHP can't spot functions that stop working correctly, but worked in previous releases. Doesn't PHP use any regression testing?
Stefan Esser: One of the biggest problem with this is that Release Candidates of PHP are not tested by the majority of people. For the PHP developers (and of course, for every vendor) it is not possible to test in all configurations or test them in all code areas. Sometimes the bugs are hidden in obscure extensions that are only used by a handful of people, or only in a code path that is usually not taken. The PHP source code has grown too fast and, although many regression tests exist, they are far from covering all code paths. (However there are currently some people working on getting more code covered by the test cases).
Do you think that security bugs should be fixed with separate patches instead of forcing users to upgrade to the latest minor release of PHP Core that fixes them, but which also include new features and potentially new/different bugs?
Stefan Esser: From my point of view, security bugs should be fixed by releasing minor releases that only contain the security bug fixes. Releasing only patchfiles is too complicated for a large number of users. PHP did both [of these] in the past (releasing new minor releases and a seperate patchfile), but due to the large number of security vulnerabilities that were reported, this was stopped, because that resulted in too many minor releases.
How do PHP5's security features compare with PHP4's?
Stefan Esser: Well, the PHP5 core does not have some of the weaknesses of the PHP4, like small 16-bit reference counters that can easily overflow. Additionally, more people use PHP's Object-Oriented features (although basic Object-Oriented features were present in PHP4). The use of objects makes some code easier to read, and fewer global variables are used which makes register_globals less dangerous.
PHP5 comes with better hashing functions by default (PHP 4 had only SHA1 and MD5). On the other hand some of the old PHP code is now vulnerable, because some things have changed. For example, the magic_quotes_gpc feature no longer includes the _SERVER/_ENV variables. Code that previously thought it does not need to prepare these, for example the USER_AGENT string, is now vulnerable.
In short I think PHP5 brought a few new things that improved security, but on the other hand it changed some internals that could have negative side-effects on old code. And of course the code base is now larger and therefore more bugs are possible.
Apache and PHP are a very common bundle. Is there any problem specific to their interaction?
Stefan Esser: Well, because Apache fails to open several file handles/sockets with the close on exec flag it is, for example, possible to takeover the httpd socket and or read/write the logfiles. Additionally, things like the SSL private key are in the memory of the httpd daemon and can therefore be leaked (this is also a problem for those following the recommendation to store the database credentials inside the httpd.conf, because I am pretty sure they can be read too).
The problem is that mod_php shares the address space with the apache daemon. Therefore any security bug in PHP that allows reading the memory will completely leak information stored by apache or other modules, in this case mod_ssl. This is not PHP specific. It is a general problem. If you find a bug in mod_python, the same should be possible with python code. It is more a problem of modules running in the same address space. The moment you are using a CGI model this is no longer an issue.
From what I've heard Apache 2 runs well with PHP. The only problem with Apache 2 is that some of its MPM modules actually are multithreaded. The problem with PHP is that it links against a lot of third party libraries that are either thread safe or not. Normally the PHP core should be thread safe. But the moment a function is called that is provided by a third-party library, one can never be sure. Therefore Apache 2 is fine as long a non-threaded MPM is used. If you use a threaded MPM it is like russian roulette depending on the extensions you are using.
From a security point of view, what is the difference between running PHP as a web server module and as a CGI binary?
Stefan Esser: Oh, that is really simple. If you are running PHP as web server module, PHP code gets executed with the permissions of the user owning the web server process. Multiple VHOSTs will all run with the same privileges and can influence each other. There are things in PHP like safe_mode or open_basedir but they can be bypassed in many ways. Therefore an exploit against one of those VHOSTs can theoretically affect other VHOSTs. Additionally exploits against the PHP core will allow access to Apache's memory. If you are using mod_ssl this allows for stealing the private key for the SSL cert from Apache's memory from within a PHP script. (Data that is normally only accessible by root - Oh I think I will demonstrate this in the Month of PHP bugs).
If you are using PHP as CGI it is possible to let the PHP scripts of different VHOSTs be executed with different Unix users. Additionally things like chrooting the PHP process are possible...