Skip to content

Commit

Permalink
Security: Attempt to block auth of nil tokens, etc.
Browse files Browse the repository at this point in the history
Some Rails authentication systems have suffered from a vulnerability
involving nil or blank login tokens:

  http://www.rorsecurity.info/2007/10/28/restful_authentication-login-security/

This patch includes a bunch of test cases testing for possible attacks
along these lines, and some sanity-checking code in our authentication
methods.

Note that the tests and the code don't really "line up" here--most of
the test methods passed already, and most of the sanity-checking code
is probably unnecessary.  But again, better safe than sorry.
  • Loading branch information
emk committed Dec 20, 2008
1 parent c500bf8 commit 64eff7f
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 0 deletions.
2 changes: 2 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ def self.find_admins(*args)

# Authenticates a user by their login name and unencrypted password. Returns the user or nil.
def self.authenticate_for(site, login, password)
return nil if site.nil? || login.nil? || login.blank? || password.nil? || password.blank?
u = find(:first, @@membership_options.merge(
:conditions => ['users.login = ? and (memberships.site_id = ? or users.admin = ?)', login, site.id, true]))
u && u.authenticated?(password) ? u : nil
Expand All @@ -55,6 +56,7 @@ def self.find_all_by_site_with_deleted(site, options = {})
end

def self.find_by_token(site, token)
return nil if site.nil? || token.nil? || token.blank?
find(:first, @@membership_options.merge(:conditions => ['token = ? and token_expires_at > ? and (memberships.site_id = ? or users.admin = ?)', token, Time.now.utc, site.id, true]))
end

Expand Down
45 changes: 45 additions & 0 deletions spec/models/user_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
require File.dirname(__FILE__) + '/../spec_helper'

describe User do
before :each do
@site = Site.make
end

def make_admin_with_token token
user = User.make(:token_expires_at => 1.day.from_now, :admin => true)
user.token = token # May be nil, so we can't pass to User.make.
user.save!
end

it "should not find users with nil token" do
# This test always passed, before we did anything specific to fix it.
make_admin_with_token nil
User.find_by_token(@site, nil).should be_nil
end

it "should not find users with empty token" do
make_admin_with_token ''
User.find_by_token(@site, '').should be_nil
end

def make_admin_with_login_and_password login, password
User.make(:login => login, :password => password, :admin => true)
end

it "should not find users with empty login" do
begin
make_admin_with_login_and_password '', 'foo'
User.authenticate_for(@site, '', 'foo').should be_nil
rescue ActiveRecord::RecordInvalid # This is OK, too.
end
end

it "should not find users with empty password" do
begin
make_admin_with_login_and_password 'joe', ''
User.authenticate_for(@site, 'joe', '').should be_nil
rescue ActiveRecord::RecordInvalid # This is OK, too.
end
end
end

0 comments on commit 64eff7f

Please sign in to comment.