Bypassing authentication in Invision Power board with CVE-2016–2564

Ian Carroll
Apr 23, 2017 · 3 min read


I discovered a potential issue with how Invision Power Board generates its session cookies, which could lead to the compromise of user sessions or the cron key. It was reported and assigned CVE-2016–2564 on 02/25/2016, fixed on 2/26/2016, and the update with the fix was released on 3/21/2016 in version 4.1.9. As far as I am aware, it was present in all 4.0 releases and all releases prior to 4.1.9.

4.1.9 fixed a few other security issues reported by me in the suite, including:

  • Timing-unsafe comparison of the cron key used in the web-exposed cron runner.
  • A type conversion issue when comparing MD5 hashes in the web-exposed cron runner, when the auto-generated cron key was a “magic hash”.
  • It was impossible to re-generate the session cookie for a given user, even if the password was changed or all sessions were logged out of.
  • The generic encryption class uses `md5(sql_password . sql_database_name)` for deriving an AES key, as well as for the IPS Connect master key. This was not resolved.


Invision Power Board takes the MD5 hash of the result of uniqid() , and uses this for various random keys. Most critically, the session key used to identify a user from the cookie uses this method. As the documentation for uniqid() warns, “This function does not generate cryptographically secure values, and should not be used for cryptographic purposes.”

uniqid() is worse than the manual makes it out to be. An example return value is 58fc30c53db63 . Already, this is only <7 bytes of entropy. But it becomes worse, because without the more_entropy flag set, PHP only uses the current time to generate the return value, as seen in the PHP source code:

The first four bytes are the current UNIX timestamp, and the last 20 bits are derived from the current time in microseconds.

This gives a bit less than 2²⁰, or one million, possible results per given second. If you are able to predict when a new session key is generated for a user, you can guess their key with a decent number of requests, depending on how accurate your guess is. On a popular forum, you may not even need to target a specific user, as the number of users logging in at one time may be large enough.

Someone with the ability to sniff the timing of encrypted traffic may be able to perform this attack with a much lower number of requests.


Invision Power Board chose to simply flip the more_entropy flag. This is still dangerous, but much harder to exploit. As seen above, this utilizes PHP’s internal LCG, which is an insecure RNG, but many more guesses are required, and are likely remotely impractical.

A better resolution would be to use random_bytes(32) , and ship the permissively licensed polyfill for it, written by Scott Arciszewski. They did not provide a reason for choosing not to use this.

It is worth noting that something may have changed in terms of their resolution between March of 2016 and today, but since I have not paid $35 to renew my license, I am incapable of checking.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store