How not to handle errors

Sometimes the code running a dynamic website will encounter errors. There are a variety of ways to handle runtime errors, of course. Some are better than others, and today I encountered a site that manages to get a surprising number of things wrong.

All I was trying to do was read a blog post. But instead of any real content, I saw just this message (suitably anonymised to protect the miscreants):

jtablesession::Store Failed
DB function failed with error number 145
Table './blah_blah_joomla15/jos_session' is marked as crashed
and should be repaired SQL=INSERT INTO `jos_session` (
`session_id`,`time`,`username`,`gid`,`guest`,`client_id` )
VALUES ( 'ckptfh6bqwy6s0yu0asgvhz1f4','1318678549','','0','1','0' )

Shall we count all the potential problems this message indicates?

  1. Session data is being stored in a database. While that’s not universally a bad idea, my experience is that it’s awkward to store any session state on the server (other than regeneratable cached data). Instead, it’s often better to set a cookie with the necessary data; if you combine that with a server-side secret and some sort of message-authentication code, like HMAC, you can happily trust the cookie data sent by the client. Then you get the pleasing benefit that your HTTP transactions are stateless, as expected.

    Let’s also note that the database this site uses for storing the session data is apparently somewhat flaky — it needs manual repair work in the event of a crash. If the site avoided storing session data on the server, that could never be a problem.

  2. It’s not apparent from just this message, but this error is being served with an HTTP status of 200 OK. This means that any automated system trying to load this page (like, for example, a search engine crawler) risks confusing it for the real content.

  3. Users who see an error page like this won’t see your site branding. Depending on the site, that might seem anywhere from a bit shoddy to shockingly unprofessional.

  4. The specific message exposes implementation details that might be valuable to an attacker. In this case, we have the database table and column names (though admittedly they were probably guessable if you knew that the site used Joomla), the database name (blah_blah_joomla15 here, though the real database name is based on the site’s domain name), and even the fact that the table files are stored immediately under the database server’s working directory.

  5. By far the worst problem, though, is that a session-handling error is preventing simple read-only access of your content. Everything else I’m pointing to here pales into insignificance compared to the simple fact that I wanted to read this blog post, and I was prevented from doing so because the site’s front-end systems had problems writing to a database. I wouldn’t be so frustrated if the error said something like “I/O error loading blog post” — that’d still mean the site has reliability problems, but at least the specific error would be impossible to work around at runtime. But it just seems overwhelmingly annoying to be prevented from reading anything at all, merely because the site internals want to allocate a server-side session for each person who drops by to read a single post. Grrr.

I note in passing that problems (2), (3), and (4) are common with systems that, like Joomla, are implemented in PHP. One of PHP’s features that’s very convenient during development is that error messages show up in the HTML output; that makes it easy for the programmer to see what’s wrong. But, judging by the number of sites which do this, it’s apparently all too easy to deploy the production site with that same feature.