diff --git a/app/models/token.rb b/app/models/token.rb index 0e8c2c3e2..a337a3cd2 100644 --- a/app/models/token.rb +++ b/app/models/token.rb @@ -15,8 +15,11 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +require 'rails_generator/secret_key_generator' + class Token < ActiveRecord::Base belongs_to :user + validates_uniqueness_of :value @@validity_time = 1.day @@ -36,9 +39,7 @@ class Token < ActiveRecord::Base private def self.generate_token_value - chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a - token_value = '' - 40.times { |i| token_value << chars[rand(chars.size-1)] } - token_value + s = Rails::SecretKeyGenerator.new(object_id).generate_secret + s[0, 40] end end diff --git a/app/models/user.rb b/app/models/user.rb index 96923900e..f48317610 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -175,8 +175,14 @@ class User < ActiveRecord::Base end def self.find_by_autologin_key(key) - token = Token.find_by_action_and_value('autologin', key) - token && (token.created_on > Setting.autologin.to_i.day.ago) && token.user.active? ? token.user : nil + tokens = Token.find_all_by_action_and_value('autologin', key) + # Make sure there's only 1 token that matches the key + if tokens.size == 1 + token = tokens.first + if (token.created_on > Setting.autologin.to_i.day.ago) && token.user && token.user.active? + token.user + end + end end # Makes find_by_mail case-insensitive diff --git a/doc/CHANGELOG b/doc/CHANGELOG index 6528e756b..07835b78e 100644 --- a/doc/CHANGELOG +++ b/doc/CHANGELOG @@ -18,6 +18,7 @@ http://www.redmine.org/ * Fixed: issues/show should accept user's rss key * Fixed: consistency of custom fields display on the issue detail view * Fixed: wiki comments length validation is missing +* Fixed: weak autologin token generation algorithm causes duplicate tokens == 2009-04-05 v0.8.3