PHP security from the inside
Stefan Esser gets set for the month of PHP bugs
Please tell us more about your 'Month of PHP bugs' initiative.
Stefan Esser: The Month of PHP bugs will take place in March 2007. Its goal is to make people and especially the PHP developers aware that bugs in PHP exist. While this sounds obvious for everyone on the outside, it is actually required. PHP has a very bad reputation when it comes to security, which is mostly caused by all the advisories about security holes in PHP applications. For some of the reported bug classes like SQL injection and XSS, this is quite unfair, because those can happen in any language. But Remote File Inclusions, vulnerabilities due to register_globals or other problems within the PHP engine (e.g. zend_hash_del_key_or_index bug) are fully to blame on the PHP language. Unfortunately this kind of thinking is not appreciated by the PHP developers and they continue to claim that PHP is not worse than other languages, and that only badly written PHP applications are the problem. The Month of PHP bugs will show however that a lot of bugs in PHP's own source code exist.
We will disclose different types of bugs, mainly buffer overflows or double free(/destruction) vulnerabilities, some only local, but some remotely trigger-able (for example, because they are in functions usually exposed to user input). Additionally there are some trivial bypass vulnerabilities in PHP's own protection features. Only holes within the code shipped with the default distribution of PHP will be disclosed. That means we will not disclose holes in extensions that only exist in PECL, while we are sure that those contain vulnerabilities, too. Most of the holes were previously disclosed to the vendor, but not all.
As a vulnerability reporter you feel kinda puzzled how people among the PHP Security Response Team can claim in public that they do not know about any security vulnerability in PHP, when you disclosed about 20 holes to them in the two weeks before. At this point you stop bothering whether anyone considers the disclosure of unreported vulnerabilities unethical. Additionally a few of the reported bugs have been known for years among the PHP developers and will most probably never be fixed. In total we have more than 31 bugs to disclose, and therefore there will be days when more than one vulnerability will be disclosed.
You said that some PHP contributors are not very security-wise developers. At the same time I can say that a lot of software written in PHP seems to have security problems, often because of bad design. Which bugs do you consider riskier?
Stefan Esser: I am quite sure that most servers are hacked through PHP application vulnerabilities and not through vulnerabilities in the PHP core. This might have been different five years ago when there was the quite easy exploitable fileupload overflow vulnerability. Therefore it is quite logical to say that a bug in an application is more dangerous. Additionally it is usually a lot easier to write an exploit for an include vulnerability or SQL injection than an exploit for a remote code execution vulnerability hidden in the core. Therefore the number of potential attackers is far higher for application vulnerabilities. It is so much easier to take over an admin account with a simple XSS vulnerability than to send carefully crafted requests to achieve a good heap layout and then trigger an overflow. Therefore I consider application vulnerabilities very risky.
On the other hand it should not be forgotten that many vulnerabilities like HTTP response splitting, mail header injection, url includes, and so on are only possible because of bad design decisions (security bugs) of PHP. Additionally there have been a number of core bugs like the zend_hash_del_key issue or the GLOBALS overwrite that introduced remote security holes into securely written applications. There have also been remote code execution vulnerabilities in PHP that allowed attacks against any server using PHP, but luckily they were not many. Knowing that there are tons of local vulnerabilities in PHP, I cannot trust any unknown PHP code because there is no way PHP can stop arbitrary machine code execution.
In short: if PHP script holes exist, an attacker will usually choose them to break into the server because this is much easier. Once he is able to execute arbitrary PHP code he can exploit the local holes to break out of open_basedir/safe_mode/disable_function restrictions and he has the same power any direct attack against the core has. On the other hand he may not need the local exploits because he is only after the SQL data.
How should we protect our SQL data?
Stefan Esser: Well Rule #1 is to only allow access to the data the web application really needs.
As long as PHP scripts are allowed to retrieve data and the Access Checks are done in PHP land there is nothing one can do about this. Stored Procedures would have to do the "security/user rights" checks itself. The moment someone is able to execute PHP code, you have lost. There are lots of functions in PHP that, for example, allow connecting to database servers directly by TCP. And even if those functions are deactivated in the configuration, PHP still has tons of local exploits that can be used to directly execute machine code.
Some people recommend putting the database credentials into the environment variables via the web server configuration, stored in files only readable by root. When the PHP script just uses these environment variables, it is not possible to see the credentials from other PHP code.
Suhosin on the other hand comes with an experimental feature that automatically prefixes a string to the username when it is sent to the database. This allows for using an empty username within the PHP script. Suhosin will prefix it with the username prefix that is configured within the VHOST. This allows two things. First of all, the full username is only known to the httpd.conf file and the database. Secondly, even if the full username leaks, another VHOST cannot use the same credentials because whatever username it supplies, it will always get it's own username-prefix prefixed. However in both cases all the database credentials can be stolen when someone gets access to the apache memory.
Have you ever looked at the WordPress source code? I'm asking this because when I did, a lot of time ago, I saw that they used just one SQL user with complete privileges. So every exploit could have deleted/copied all your data. The crazy thing is that WordPress is now one of the most used blogging platforms on the planet. If you'd like, you could instead comment on the security of some big/known software written in PHP that you had time to test...
Stefan Esser: Well, I released two WordPress advisories recently. From my point of view, WordPress is not well designed. This starts for example with the fact that they are escaping all input for the database in the beginning, and later when issuing the queries they just put variables directly into the query. The bug I released (charset conversion SQL injection) would not have been possible if they had chosen the more common design, to escape everything right before it is put into the query. Others might argue that they should better use prepared statements and variable binding, but WordPress has to be compatible with old MySQL databases and PHP installations that do not support this. Another problem of WordPress is that it is sooo user friendly that it spits out detailed error messages when a SQL query fails, such that a potential attacker can gain information about the query. This for example leaks the database table prefix.
The problem with many of these big PHP applications like WordPress and PHPBB is that they were started in the days when security was not taken so seriously, and from that day they have grown and grown. In many cases it would have been better to just rewrite them from scratch, but that is of course a lot of work and most people don't like the idea.
This article originally appeared in Security Focus.
Copyright © 2007, SecurityFocus
Federico Biancuzzi is freelancer. In addition to SecurityFocus he also writes for ONLamp, LinuxDevCentre, and NewsForge.