What's wrong with PHP (Part 2)

Filed under: php 

My previous article was quite inflammatory: it was a personal rant never meant to see wide dissemination. I make no apologies for its content, however I do apologise to those who came expecting to see a reasoned argument supporting my assertions and came away rightly disappointed. I'll try to remedy that here and perhaps spark a more intelligent discussion than what was had previously.

Before we start, if your comment consists of "you're just a two-bit blogger looking for fame" or some variation of, try to save yourself the pitiful fate of self-fulfilling prophecy. Posting a comment under those pretenses is a bit like trying to put a store out of business by buying all their merchandise. It's probably not going to work. If you don't want me to be famous, go away. It's really for the best.

Part 1: PHP Points the Gun at Your Head

A common adage is that [insert language or tool] will let you shoot yourself in the foot. PHP helps you out even further by just finishing you off for good.

I just thought I'd get that out of the way in case anyone made the mistake of thinking I had softened on my position any.

Let's start out with a list of assumptions, of which I don't think there can be much disagreement

  1. PHP is widely assumed to be a good language for beginners.
  2. PHP is mainly targeted at web applications
  3. PHP has a configuration file with dangerous options in it
  4. Many poorly-written PHP applications require that one or more of those options be turned on in order to function.

Whether the designers of PHP intended it to be or not, PHP is widely considered to be a good beginner's language, probably due to its low barrier to entry. Whether they wanted it or not, that's what they've got and this fact must be recognized and accounted for.

Let's go over the various settings in php.ini that can open serious security holes:

  1. register_globals - this injects user-supplied data into the global namespace
  2. allow_url_fopen - allows remote URLs to be opened as if they are local files
  3. magic_quotes_gpc - pretends to protect you from malicious input

Now, before we start, let's just know that these days, PHP ships with these turned off by default. You have to enable them yourself. Exactly how much protection does this provide? Well it would depend on your level of expertise and whether you realized the implications of what you were doing. Many popular PHP apps require that one or more of these be turned on in order to function. If you are a novice PHP programmer (or just a hapless user following installation instructions), then you are quite likely to just do what you are told by people who apparently know more than you (the developers of said PHP application would appear to be experts). And after all, if they were that dangerous, why would the PHP devs provide them in the first place. That's a very good question.

Now, it's been argued that no moderately knowledgable PHP user would fall prey to such well-known exploits. I think the Mambo developers would beg to differ. Mambo, just in the last few months, fell prey to a combination of register_globals and allow_url_fopen which allowed malicious users to overwrite a global variable which contained the name of a Mambo include file and force Mambo to include arbitrary (and I'd expect malicious) PHP code from anywhere in the world and execute it. Now if the PHP experts working on Mambo can't avoid this obvious pitfall, what chance does a beginner have? That's a rhetorical question, btw.

magic_quotes_gpc is a bit more benign, not providing any direct exploits itself, but rather lulling the programmer into a false sense of security. It purports to sanitize user input to help prevent SQL injection attacks and the like. The problem is it only works on a subset of potential malicious input, doesn't deal with two byte characters and also prevents you from doing it right and using prepare() or one of its variants (you get double escaping if you do both, so backslashes appear in your data). Therefore if, magic_quotes_gpc is enabled, the programmer will have to work that much harder to sanitize input. Except of course they probably won't. If you do some quick tests, it appears to work just fine. Most beginners probably wouldn't even do that, but even if they did, there would be little to raise alarms.

Now, if a beginner were just writing their own code, chances are they would not tamper with php.ini. However, I expect that most beginners are going to install one or more existing PHP applications: a blog, a bulletin board... whatever. There's at least a respectable chance that one or more of these applications will want one or more of those settings on in order to function. The stage is set for that user to unwittingly write exploitable code.

If PHP is to truly be a beginner's language (or apparently a language for anyone, judging from the Mambo exploit), then it needs to be a little more difficult to point the gun at your head. Ideally those options would just be removed altogether from PHP. If for some unfathomable reason this can't be done, then perhaps leaving them as compile-time flags would be slightly better (although still not a good idea IMO).

We are talking about a language, targeted at beginners, interfaced via the most hostile environment possible (the internet), with all the cards stacked against the programmer. What could possibly go wrong?



55 comments Leave a comment