PHP security, an oxymoron?

I’m in the finishing phase in the development of a medium sized web application and would like to share some of my findings.

The system is developed in PHP for two reasons:

  • The LAMP platform is a well accepted one and finding hosting companies supplying it or convincing the IT administrator to deploy it internally
  • I’ve been programming in PHP longer than any of those platforms. However easy it may be to learn RoR or Seaside or something else, it takes considerably less time for me to go with PHP. On the long run I intend to dabble with those systems, this just wasn’t the project for it.
  • This system is a mildly critical one (meaning that it should not have downtimes longer than 30 minutes during the day) and I felt that PHP is the only language I know deep enough to create robust code and make suggestions in the configuration of the environment which would lead to better stability and security.

I also considered using something like Symfony or CakePHP for the project, however I decided against this also, for the following reason:

  • With Symfony I got the impression that I was getting everything and the kitchen sink without any easy method to create a minimalist system and add on the components which were needed.
  • An other concern of mine regarding Symfony was that I could not find any security documentation for it. Being a security guy this bothered me a lot, especially since it was clear that I would not have time to read through all its source code.
  • With CakePHP the situation was a little better, there is a lot less code to start with and I also found some security documents which described how you can place the framework directory anywhere you like (and I would like it very much outside of my web tree, thank you). An annoying thing about CakePHP is that they beg for money on their website. I can understand the donation buttons on the site, since probably they’ve put a lot of work in it, but displaying the donation buttons so prominently when you try to download it, giving the impression that you have to pay for it seems just wrong.

Finally I decided against using any MVC frameworks since I haven’t fully grokked the concept yet and I felt that separating the project in 3 parts was a little unnatural. I went with a 2.5 tier application where most of the database access is done by an ActiveRecord type of class and the controllers interface directly with it very seldomly (when I have to do selects from multiple tables or something like that). For the database access layer I decided for ADOdb which is IMHO the best currently out there (including Pear::DB and PDO). It has the advantage of (really) supporting parametrized queries (unlike Pear::DB which just pretends to support it), so I don’t have to worry about SQL injections and I can write much cleaner code. Most of the standard steps (like fetching a single value from a single row) can be accomplished in one step. I truly feel that this is the equivalent of the Perl DBI for PHP (and also for Python!).

This is also the first time I used the (very limited) OO capabilities of PHP. They are truly very limited! PHP5 improved on them a lot (the most notable improvement being the policy that all objects are passed by reference and the adding of destructors), but sadly I don’t have the luxury of targeting PHP5 only. Still, OO in PHP4 helps a lot, most notably with namespacing issues.

To add AJAXy features to the application I used a combination of hand written Javascript with the Yahoo! UI framework and the DynArch calendar. I looked at Dojo Toolkit, which looked very promising, but the fact that their website simply freezes most browsers for a couple of seconds (!) while it loads all the Javascript, put me off. One thing I observed is that it’s really hard to find environmentally friendly Javascript code out there (code that puts all its stuff in a separate namespace and doesn’t overwrite the event handlers already assigned to elements), which is really sad.

A note about the editors used: for this project I experimented with the new free Komodo Editor and it turned out pretty good. They got a decent syntax highlighting and auto completition (although it doesn’t work across files, which I don’t understand, since this should be the point of creating a project with all the files, shouldn’t it?). An other complaint of mine is that it works rather sluggishly over RDP connections, which must be related to the way it does its screen refresh, since other editors had no problems over the same connection. Other nice editors I used are Notepad2 and jEdit. The advantage of the first is that it requires no install and of the second that it has many useful plugins and is cross-platform, but it requires the JVM.

Given that I didn’t use a particular framework, I did the deployments manually with WinMerge, which helped in the preservation of the server specific configurations (and also has a great feature where it can convert from Linux to Windows line endings and vice-versa).

Now for security: being the security geek I am, I really tried to take all the steps necessary to safeguard information in the application (one of them being the writing of a PHP script to serve up static files – style sheets, javascripts, images, etc – rather than letting Apache do it, so that I could add authentication to it if necessary). However after reading this article about the coming month of PHP bugs I don’t feel confident any more that publicly facing websites should run PHP, or at least not without additional security measures like mod_security and Suhosin. Everything that Stefan Esser says sounds well founded and not as a personal attack and paints a sad picture of the (probably) most widely used server side scripting language. The good news is that all is not lost and the fact that most of the time the scripts themselves are exploited rather than the PHP engine, means that it is improving (although slowly). Just to verify some of his claims (as should you), I looked at the release history of PHP 5. Here is the time it took release a given version:

  • 5.2.1 – 98
  • 5.2.0 – 70
  • 5.1.6 – 7
  • 5.1.5 – 105
  • 5.1.4 – 112
  • 5.1.3 – 0
  • 5.1.2 – 45
  • 5.1.1 – 4
  • 5.1.0 – 80
  • 5.0.5 – 158
  • 5.0.4 – 106
  • 5.0.3 – 83
  • 5.0.2 – 42
  • 5.0.1 – 30

On average it took them more than two moths (67 days) to release a new version. If you add to the mix the fact that big businesses value stability and tend to install updates later than sooner, we will see the majority of systems patched against the flaws which will appear no sooner than mid-July. So practice due diligence, make your system available only to those who need it (and enforce this policy by the firewall and the server configuration) and watch your systems as these vulnerabilities start to appear.

PS. There is an interesting writeup on Alex’s blog on how you can turn a local file inclusion vulnerability into a remote one with a little help from PHP. So make sure that you don’t include dynamically files in your project, or if you have to, validate the file names to make sure that they don’t contain slashes, backslashes or any other dubious characters (the most ideal solution would be to check against an array of filenames which are considered valid).

Leave a Reply

Your email address will not be published. Required fields are marked *