The sources and methods we've been using for the generation of security
tokens in our code has been either fairly inadequate or has system support
issues.
-- TL;DR portion --
In the installer we try to use /dev/urandom directly. While this is a good
source it's not available in some situations. And if it's not available,
then we all the way back to nearly the weakest random number generator we
could have.
For the generation of user_token we take the secret key generated during
installation (or use microtime if not available), combine it with mt_rand(
0, 0x7fffffff ), the wiki id, and the user_id and the md5 it.
Given that both the wiki id and the user id are public and mt_rand is weak
we basically rely entirely on the secret key. If the secret key is leaked
then it becomes a mere matter of time before one could find out what token
was used by trying the possible values of mt_rand. And the entire
user_token column needs to be reset.
Also given that people regularly post their LocalSettings.php in
#mediawiki and some forget to strip out their $wgSecretKey it would be a
good idea to not depend so heavily on the secret key actually being secret.
For the generation of other security tokens like email confirmation tokens
and temporary passwords we use nothing but mt_rand() not even bothering to
see if there is a proper source of random data.
-- END --
In light of that, I've built a new MWCryptRandom class intended to be used
in the installer for generating tokens, when generating user_token, and
when generating other cryptographic random tokens.
The class is in-part based on Drupal's drupal_random_bytes[1] method, some
of our own code, some code I had written prior to writing this (eg: I had
already planned to use openssl_get_random_bytes in User::setToken before I
wrote this), and some extras added into the theory based on what we have
available.
Since it's security related I'd like people to look over the code and give
some feedback on it.
The class was committed in r111964 but backed out till after the git
migration:
https://www.mediawiki.org/wiki/Special:Code/MediaWiki/111964
If you want to try out and test the class yourself you can get it into
your trunk svn checkout by using:
$ svn merge -c 111964 .
[1]
http://api.drupal.org/api/drupal/core!includes!bootstrap.inc/function/drupa…
--
~Daniel Friesen (Dantman, Nadir-Seen-Fire) [
http://daniel.friesen.name]