WordPress 2.5 cookie integrity protection vulnerability

Recently, I was preparing to give a talk on web authentication so was looking at the source code of WordPress, which I had just upgraded to version 2.5. Unfortunately, I found a rather nasty security hole, which has now been disclosed. If a WordPress installation is configured to permit account creation, the vulnerability allows an attacker to gain administrator access.

The problem is to do with how cookies are generated. The authentication code was substantially overhauled for WordPress 2.5, in part to deal with security problems in the password database. Now, the authentication cookies take the form of:

wordpress_.COOKIEHASH = USERNAME . | . EXPIRY_TIME . | . MAC

Where:
COOKIEHASH
MD5 hash of the site URL (to maintain cookie uniqueness)
USERNAME
The username for the authenticated user
EXPIRY_TIME
When cookie should expire, in seconds since start of epoch
MAC
HMAC-MD5(USERNAME . EXPIRY_TIME) under a key derived from a secret and USERNAME . EXPIRY_TIME.

This scheme is based on two papers: Dos and Don’ts of Client Authentication on the Web by Fu et al. and A Secure Cookie Protocol by Liu et al. However, there is a small difference and, as is common in cryptographic systems, small changes can have big impact.

The problem is that USERNAME and EXPIRY_TIME are not delimited when calculating the MAC. This means that a MAC for one cookie is valid for any other, provided that USERNAME . EXPIRY_TIME is unchanged. So an attacker can register a username starting with “admin”, log in as usual, then modify their cookie so it’s valid for the administrator account.

Fu et al. called this the “cryptographic splicing” attack in their paper (Section 3.3), and is one of the many ways they show how people can slip up when implementing web authentication. Unfortunately, dynamic website frameworks, especially PHP, offer little assistance to programmers trying to implement secure applications.

I will expand on this topic in a future post but in the mean time, if you run WordPress, you really should upgrade to 2.5.1. While WordPress 2.3.3 doesn’t have the problem described here, it is still not secure.

There is some more detail on the cookie vulnerability in my disclosure (CVE-2008-1930). WordPress have mentioned it in their release announcement and I’ve also just sent it to the usual mailing lists.

11 thoughts on “WordPress 2.5 cookie integrity protection vulnerability

  1. Very interesting blog post, but what is the purpose of these authentication cookies in the first place? To automatically log people in? (Sorry, I am not familiar with WordPress.)

  2. @Steven,

    At least they tried to get it right, which is a lot more than most web developers attempt.

    They might not have succeded but it’s a whole lot better than one financial institution who put the authentication code into the client code… Oh and got the code from a programing example in a book… for the sake of their developers (who are a much abused lot) I shall not mention the organisation.

    As you note security is never easy it has to be 100% from day one which lets be honest is not even a good prospect for experianced professionals in the field of endevor.

    Also it is not something you can leave to the supposed experts either. Think about probs with crypto libraries and networking standards etc.

    So the probability of getting a new system right first time is not that good even for the “best in breed” 8)

    Also it was just luck you where able to spot the mistake when you did, how long would it have gone unnoticed if you had not had the time to be curious?

  3. @Ivan

    WordPress sets cookies so it can identify who is carrying out a particular action. Otherwise users would need to enter their password every time they do something which is access-controlled.

    If the user chooses to make their cookie permanent, it will automatically log them in next time they come to the site. If not then the cookie will be deleted when the user closes the browser.

  4. @clive

    At least they tried to get it right

    This is potentially hundreds of thousands of people’s security, not some test in the Lower Fourth where you score points for a plucky try.

    Getting this sort of basic thing wrong is negligent, and only a quaint view that it somehow doesn’t matter, prevents them from having to take full responsibility.

    Also it is not something you can leave to the supposed experts either. Think about probs with crypto libraries and networking standards etc.

    There’s plenty of blame to go around, that’s for sure. But that’s not any sort of excuse. If this was some mechanic who’d failed to tighten the bolts on your wheels so it came off on the second corner, I don’t think you’d be saying “think about the problems with the design of the Pinto!”

  5. @Steven,

    Thank you for the clarification about the authentication cookies. I am very surprised to learn the WordPress developers had decided to create their own session mechanism, choosing not to simply use the implementation that comes with PHP. It would be very interesting to hear if they had a good reason for re-inventing the wheel–although I doubt they did.

  6. Richard,

    Although I agree with you that security could and should be a whole lot better, I’m also a realist on such matters.

    As has been noted in the recent past (by an ex member of the Bush Admin) there are,

    1) Known, Knowns
    2) Known, Unknowns
    3) Unknown, Unknowns.

    The latter two indicate that 100% security is going to be at best quite difficult and further a continuously moving target.

    Also there is perspective, you say

    “Getting this sort of basic thing wrong is negligent”

    There are two things, your perspective on,

    1) the level of the domain complexity (basic), and also on,
    2) if the due diligence the developers did was sufficient (negligent).

    Based on your view and to play devil’s advocate, it could be argued that Steve was more negligent than the WordPress developers, after all he obviously had the required capabilities (he found the problem) and it would have been (possibly) “basic to him” but he did not audit the software before he deployed it therfore he was negligent.

    Would I personaly say Steve was negligent, very probably not for two reasons first I do not know enough of the circumstances, and secondly I take the view that resources are finite and that there use has to be proportionate to both the task and risk.

    My original point was that as 100% security is at best illusiory the fact that the WordPress solution although now known to be broken was a considerable improvment on what others in the industry would consider proportianate. Further although it is now obvious with hindsight how obvious would it have been prior to Steve finding it?

    And finaly there is the level of skill of the developers, not just in their part of the industry but in the area of “security audit”.

    As I noted in my previous post even “domain experts” get it wrong from time to time so there is still a reasonable posability that a domain expert would have missed it.

    Which brings up the question of just how many properly qualified domain experts are there to projects that need them?

    I suspect that the number of domain experts is very very much less than projects.

    Now I don’t know about you but I like to sleep occasionaly 😉

  7. While things need to get done, using PHP and MySQL and Fedora, sure do not seem to be a solid foundation. Sure, building sand castles might be ok, one has no expectation of security.
    What is funny, is that there are a lot of self labeled ‘security experts,’ who really are insecurity reporting experts, along with some insecurity experts as well.
    What is needed, is security experts, those who use tools that one would hope to get some security out of. Who cares about reports, I want a product!

    I really enjoy lightbluetouchpaper and articles! But why use poor software?

    Seems like black sheep, useful for accounting purposes, if your can run it with results, then whatever…

    Why not run *BSD and other blog, like maybe MovableType? Perhaps then experienced professionals, have a chance to get more right.

  8. @2usewhat?:
    “Who cares about reports, I want a product!”

    Tsk, tsk. Security is not a product, it is a process!

    “While things need to get done, using PHP and MySQL and Fedora, sure do not seem to be a solid foundation”

    LAMP has got nothing to do with it. Sure, because the price is right, LAMP is the tool-set of choice for absolute novices, and such people often make elementary blunders. But it is perfectly possible to build secure sites on LAMP, just as it is possible to build insecure ones on J2EE, .NET or what-have-you — and even experienced developers often do.

    The critical factor is not the platform choice, but a security mind set. In this case, the critical blunder by the WordPress developers was attempting to build their own cryptographic mechanisms (specifically, a secure session cookie.) Such mechanisms are notoriously difficult to get right, and should be left to experts in that domain — and even then opened to the public and scrutinised to the n’th degree before being trusted.

    It happened also to be unnecessary, since as Ivan Ristic pointed out, PHP in fact already has a built-in session mechanism that was designed by experts, and has been vetted in public (and gradually refined) for many years. On some other platforms, you simply have no idea (for example, an early version of the ASP.NET session mechanism had a buffer overflow vulnerability — despite itself being written in .NET, in which “unchecked buffers are impossible” — that in some cases might allow execution of arbitrary code at the privilege level of the ASP.NET worker.)

  9. Steven, I wonder if you could elaborate on the following remark:
    “Unfortunately, dynamic website frameworks, especially PHP, offer little assistance to programmers trying to implement secure applications.”
    Are you referring to poor libraries or that the language itself stands in the way? I’d be very interested in any thoughts you have on how a web framework could aid the programming in developing secure applications.

  10. @Josef

    It seems like a lot of web applications are re-inventing their own cryptography (session cookies, XRF nonces, password hashing), and generally getting them wrong. If PHP were to implement these functions, this would go a long way to helping resolve the problem.

    The cryptographic primitives that PHP offers are also quite poor. For example, the default password salting algorithm is the old DES-based system, despite better alternatives being available.

    In general, I think framework authors should look at commonalities between web applications, and give higher-level primitives. Only offering low-level ones, like MD5 or HMAC, is forcing application authors to develop their own protocols, which is a notoriously difficult task.

    These functions should also be a standard part of the framework, so guaranteed to be available at any web-hosting provider. Web application authors know that many of their users cannot install extra modules, so adding new libraries won’t help.

  11. @ Richard, Steven,

    I was chatting to a colleague just a day or so ago and they pointed out that I was perhabs being a little unfair, further that I was indanger of falling into “2usewhat?”s catagories,

    “’security experts,’ who really are insecurity reporting experts, along with some insecurity experts as well.”

    In that I did not “offer a solution” and say how I deal with the issues of “No 100% security” within my stated view,

    “… that resources are finite and that their use has to be proportionate to both the task and risk.”

    So put simply I turn the problem on it’s head and think in the reverse direction to meet the objectives,

    Firstly I assume that a preventative security solution can only address known security flaws and a limited subset of (predictable) unknown flaws. Further that over time new attack vectors will be discovered that could not have been predicted at the time the security solution was desiged / built.

    Therefore no matter how strong a preventative security solution is over a sufficient period of time it is not going to offer anything other than an illusion of security (yup it’s not what the security product sales people want people to hear).

    Secondly I assume from this that it will require a disproportianate effort to try and design a preventative system for anything other than known or reasonably assumed attack vectors.

    From this it can be seen that any purly preventative security system is destined to fail and be significantly over engineered in the process.

    Then there is the issue that at some point a new unknown attack vector will be used and all reasonable preventative security systems in place will fail. But that there is unlikley to be any real warning that a security system is now vulnerable.

    Therefore you need to be able to detect when a systems has been compromised in a reliable way, and then take the appropriate measures.

    So insted of looking at “prevention” as the solution I look at “detection” then “response” as a more proprtianate way to do things.

    After all how tall could building technology alow you to make your citadel walls and keep before somebody invented the maned kite cannon or hot air ballon?

    Incidently this “Detect respond” view point is the one usually used for high value physical targets on public display and has a reasonable pedigree (but is not perfect which is why people buy insurance cover 8)

    I have had this view point for a considerable period of time, and I have frequently put it into practice. As a simple example of putting your money where your mouth is 😉

    Back in the mid 90’s I was asked to design/build a public secure web server for an organisation the main aim being to prevent defacement of pages. Although frequently updated by the organisation (as often as every half hour or so) the pages where effectivly static.

    The organisation was not best pleased when I told them that what they where asking for (100% gaurentee) was not possible (it still is not today). After an initial uncomftable silence I was asked by the business owner if there was a way to achive a similar objective.

    I pointed out that as it was not possible to 100% prevent defacement, then the next best was to detect it and deal with it in a reasonable time frame. It was on this assumption that the system was designed and built and was working for a number of years.

    In essence the design consisted of the public facing web server running as a slave. It’s pages where updated from a master web server that was issolated from the outside world. The detection process was on a third machine that had access to the output of both the master and slave webservers and compared their content on a page by page basis on a continuous cycle. If there was a disegrement between the master and slave content then it raised an alarm process that did some further checking before responding with an appropriate action.

    Although fairly low tech it did what it was supposed to do, and on one occasion dealt with an attack via an unknown (at the time of the attack) method. Also as a side effect it reduced the stress on the sysadmin (who was a friend 😉

    The downsides of the system was that as well as not being 100% secure it also did not have 100% uptime, but sometimes you have to compramise on what your goals are in terms of task, risk and resources.

    Also it was not suitable for a number of web based activities that are now regarded as standard.

Leave a Reply

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