We've discovered and patched an issue where user accounts can potentially be compromised via token prediction.
We've released fixes for all known operational Alavetelis.
Summary and Impact:
===================
Password reset tokens are generated using Ruby's rand(), which is not cryptographically secure. An attacker can observe tokens leaked in login redirect URLs, and under the right circumstances (one process running Alaveteli, little other uses of rand on the device it runs on) may be able to predict future password reset tokens, and thus gain access to change the password of a user account, given the email address (unless it is protected by two factor authentication).
Fix:
====
The fix is to commonlib/rblib/util.rb. As MySociety::Util.generate_token has been using rand() instead of SecureRandom, the fix is to have it use SecureRandom.
We have released fixed versions for all known operational Alaveteli installs. These are listed below.
We also attach a generic patch file that should work with any version of Alaveteli since the vulnerability was introduced. Note that as the vulnerability resides in the commonlib git submodule, you will need to apply it by changing into the commonlib directory and then apply the patch:
cd path/to/alaveteli
cd commonlib
git am Ruby-Use-SecureRandom.hex-in-generate_token.patch
Here's the diff:
diff --git a/rblib/util.rb b/rblib/util.rb
index 8db3644..3e968fd 100644
--- a/rblib/util.rb
+++ b/rblib/util.rb
@@ -7,16 +7,13 @@
#
#
require 'openssl'
+require 'securerandom'
module MySociety
module Util
# Makes a random token, suitable for using in URLs e.g confirmation messages.
def self.generate_token
- bits = 12 * 8
- # Make range from value to double value, so number of digits in base 36
- # encoding is quite long always.
- rand_num = rand(max = 2**(bits+1)) + 2**bits
- rand_num.to_s(base=36)
+ SecureRandom.hex(14)
end
# breaks a list of items into a hash keyed by first letter of their descriptor block
Note that in later versions we've used SecureRandom.alphanumeric. This is unavailable before Ruby 2.5, which affects some Alaveteli installs. If you're on an older install and need to patch instead of upgrade to one of the new releases, then hex is more generally compatible until you can get to a later version. We strongly recommend upgrading to more recent versions of Ruby and Alaveteli, as other security issues will have been patched.
Affected versions:
==================
This vulnerability was introduced in 2007, and all versions are affected.
Fixed versions:
===============
We have published hotfix releases for the below series of Alaveteli and merged a fix to the master branch.
https://github.com/mysociety/alaveteli/releases/tag/0.46.2.1https://github.com/mysociety/alaveteli/releases/tag/0.46.1.2https://github.com/mysociety/alaveteli/releases/tag/0.46.0.3https://github.com/mysociety/alaveteli/releases/tag/0.44.0.3https://github.com/mysociety/alaveteli/releases/tag/0.43.2.2https://github.com/mysociety/alaveteli/releases/tag/0.42.0.2https://github.com/mysociety/alaveteli/releases/tag/0.41.1.2https://github.com/mysociety/alaveteli/releases/tag/0.38.4.5https://github.com/mysociety/alaveteli/releases/tag/0.38.1.3https://github.com/mysociety/alaveteli/releases/tag/0.24.1.14https://github.com/mysociety/alaveteli/releases/tag/0.23.2.8As ever, reach out if you have any questions.
Best,
Gareth