mirror of
https://github.com/heartcombo/devise.git
synced 2026-01-10 08:08:00 -05:00
fix for possible injection with mongo
Signed-off-by: José Valim <jose.valim@gmail.com> Conflicts: lib/devise/models/authenticatable.rb test/integration/token_authenticatable_test.rb test/models/token_authenticatable_test.rb
This commit is contained in:
@@ -90,6 +90,12 @@ module Devise
|
||||
# end
|
||||
#
|
||||
def find_for_authentication(conditions)
|
||||
#the to_s is here to avoid mongodb injection where 'field => value' becomes 'field => {$ne => value}' thourgh the magic of rails
|
||||
#still this does not prevent the leak if user1.token == '$ne' + user2.token (the chance of that is poor though)
|
||||
#this might not be the best place or the best method, please change
|
||||
conditions.each do |k, v|
|
||||
conditions[k] = v.to_s
|
||||
end
|
||||
find(:first, :conditions => conditions)
|
||||
end
|
||||
|
||||
|
||||
@@ -65,6 +65,31 @@ class TokenAuthenticationTest < ActionController::IntegrationTest
|
||||
end
|
||||
end
|
||||
|
||||
test 'authenticate with valid authentication token key and do not store if stateless and timeoutable are enabled' do
|
||||
swap Devise, :token_authentication_key => :secret_token, :stateless_token => true, :timeout_in => (0.1).second do
|
||||
user = sign_in_as_new_user_with_token
|
||||
assert warden.authenticated?(:user)
|
||||
|
||||
# Expiring does not work because we are setting the session value when accessing it
|
||||
sleep 0.3
|
||||
|
||||
get_users_path_as_existing_user(user)
|
||||
assert warden.authenticated?(:user)
|
||||
end
|
||||
end
|
||||
|
||||
test 'should not be subject to injection' do
|
||||
swap Devise, :token_authentication_key => :secret_token do
|
||||
user1 = create_user_with_authentication_token()
|
||||
user2 = create_another_user_with_authentication_token(:auth_token => "ANOTHERTOKEN")
|
||||
|
||||
visit users_path(Devise.token_authentication_key.to_s + '[$ne]' => user1.authentication_token)
|
||||
|
||||
assert warden.user(:user) == nil
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def sign_in_as_new_user_with_token(options = {})
|
||||
@@ -85,4 +110,33 @@ class TokenAuthenticationTest < ActionController::IntegrationTest
|
||||
user
|
||||
end
|
||||
|
||||
def create_user_with_authentication_token(options = {})
|
||||
user = create_user(options)
|
||||
user.authentication_token = options[:auth_token] || VALID_AUTHENTICATION_TOKEN
|
||||
user.save
|
||||
user
|
||||
end
|
||||
|
||||
def create_another_user_with_authentication_token(options = {})
|
||||
@anotheruser ||= begin
|
||||
user = User.create!(
|
||||
:username => 'anotherusertest',
|
||||
:email => options[:email] || 'anotheruser@test.com',
|
||||
:password => options[:password] || '123456',
|
||||
:password_confirmation => options[:password] || '123456',
|
||||
:created_at => Time.now.utc
|
||||
)
|
||||
user.confirm! unless options[:confirm] == false
|
||||
user.lock_access! if options[:locked] == true
|
||||
user.authentication_token = options[:auth_token] || VALID_AUTHENTICATION_TOKEN
|
||||
user.save
|
||||
user
|
||||
end
|
||||
end
|
||||
|
||||
def get_users_path_as_existing_user(user)
|
||||
sign_in_as_new_user_with_token(:user => user)
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
@@ -34,4 +34,26 @@ class TokenAuthenticatableTest < ActiveSupport::TestCase
|
||||
assert_nil authenticated_user
|
||||
end
|
||||
|
||||
end
|
||||
test 'should not be subject to injection' do
|
||||
|
||||
if DEVISE_ORM != :mongoid
|
||||
assert_nil(nil)
|
||||
else
|
||||
|
||||
user1 = create_user
|
||||
user1.ensure_authentication_token!
|
||||
user1.confirm!
|
||||
|
||||
user2 = create_user
|
||||
user2.ensure_authentication_token!
|
||||
user2.confirm!
|
||||
|
||||
#now trick it
|
||||
user = User.find_for_token_authentication(:auth_token => {'$ne' => user1.authentication_token})
|
||||
|
||||
assert_nil user
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user