Compare commits

...

7 Commits

Author SHA1 Message Date
José Valim
02a2976f5e Release v2.2.6 2013-08-09 10:31:54 +02:00
José Valim
a44002c68b Fix the build 2013-08-09 10:21:22 +02:00
José Valim
60f3c678e6 Skip storage for cookies on unverified requests 2013-08-09 09:33:19 +02:00
José Valim
81141bb9c8 Update Gemfile.lock 2013-08-02 23:45:31 +02:00
José Valim
373fd03ebc Release 2.2.5 2013-08-02 23:24:17 +02:00
José Valim
b3eace20c7 Update CHANGELOG 2013-08-02 23:22:39 +02:00
José Valim
415fa2ad21 Protect against CSRF token fixation attacks 2013-08-02 23:16:32 +02:00
14 changed files with 75 additions and 25 deletions

View File

@@ -1,3 +1,13 @@
== 2.2.6
* bug fix
* Skip storage for cookies on unverified requests
== 2.2.5
* bug fix
* Clean up CSRF token after authentication (by @homakov). Notice this change will clean up the CSRF Token after authentication (sign in, sign up, etc). So if you are using AJAX for such features, you will need to fetch a new CSRF token from the server.
== 2.2.4
* enhancements

View File

@@ -1,7 +1,7 @@
PATH
remote: .
specs:
devise (2.2.4)
devise (2.2.6)
bcrypt-ruby (~> 3.0)
orm_adapter (~> 0.1)
railties (~> 3.1)
@@ -38,7 +38,7 @@ GEM
i18n (= 0.6.1)
multi_json (~> 1.0)
arel (3.0.2)
bcrypt-ruby (3.0.1)
bcrypt-ruby (3.1.1)
builder (3.0.4)
erubis (2.7.0)
faraday (0.8.7)
@@ -129,7 +129,7 @@ GEM
polyglot
polyglot (>= 0.3.1)
tzinfo (0.3.37)
warden (1.2.1)
warden (1.2.3)
rack (>= 1.0)
webrat (0.7.3)
nokogiri (>= 1.2.0)

View File

@@ -1,7 +1,7 @@
PATH
remote: ..
specs:
devise (2.2.4)
devise (2.2.6)
bcrypt-ruby (~> 3.0)
orm_adapter (~> 0.1)
railties (~> 3.1)
@@ -39,7 +39,7 @@ GEM
activesupport (3.1.12)
multi_json (~> 1.0)
arel (2.2.3)
bcrypt-ruby (3.0.1)
bcrypt-ruby (3.1.1)
builder (3.0.4)
columnize (0.3.6)
erubis (2.7.0)
@@ -139,7 +139,7 @@ GEM
polyglot
polyglot (>= 0.3.1)
tzinfo (0.3.37)
warden (1.2.1)
warden (1.2.3)
rack (>= 1.0)
webrat (0.7.3)
nokogiri (>= 1.2.0)

View File

@@ -221,6 +221,10 @@ module Devise
mattr_accessor :omniauth_path_prefix
@@omniauth_path_prefix = nil
# Set if we should clean up the CSRF Token on authentication
mattr_accessor :clean_up_csrf_token_on_authentication
@@clean_up_csrf_token_on_authentication = true
def self.encryptor=(value)
warn "\n[DEVISE] To select a encryption which isn't bcrypt, you should use devise-encryptable gem.\n"
end

View File

@@ -21,6 +21,7 @@ module Devise
# Remembers the given resource by setting up a cookie
def remember_me(resource)
return if env["devise.skip_storage"]
scope = Devise::Mapping.find_scope!(resource)
resource.remember_me!(resource.extend_remember_period)
cookies.signed[remember_key(resource, scope)] = remember_cookie_values(resource)

View File

@@ -0,0 +1,5 @@
Warden::Manager.after_authentication do |record, warden, options|
if Devise.clean_up_csrf_token_on_authentication
warden.request.session.try(:delete, :_csrf_token)
end
end

View File

@@ -1,4 +1,5 @@
require 'devise/hooks/activatable'
require 'devise/hooks/csrf_cleaner'
module Devise
module Models

View File

@@ -3,9 +3,16 @@ module Warden::Mixins::Common
@request ||= ActionDispatch::Request.new(env)
end
# This is called internally by Warden on logout
NULL_STORE =
defined?(ActionController::RequestForgeryProtection::ProtectionMethods::NullSession::NullSessionHash) ?
ActionController::RequestForgeryProtection::ProtectionMethods::NullSession::NullSessionHash : nil
def reset_session!
request.reset_session
# Calling reset_session on NULL_STORE causes it fail.
# This is a bug that needs to be fixed in Rails.
unless NULL_STORE && request.session.is_a?(NULL_STORE)
request.reset_session
end
end
def cookies

View File

@@ -1,3 +1,3 @@
module Devise
VERSION = "2.2.4".freeze
VERSION = "2.2.6".freeze
end

View File

@@ -76,6 +76,12 @@ Devise.setup do |config|
# passing :skip => :sessions to `devise_for` in your config/routes.rb
config.skip_session_storage = [:http_auth]
# By default, Devise cleans up the CSRF token on authentication to
# avoid CSRF token fixation attacks. This means that, when using AJAX
# requests for sign in and sign up, you need to get a new CSRF token
# from the server. You can disable this option at your own risk.
# config.clean_up_csrf_token_on_authentication = true
# ==> Configuration for :database_authenticatable
# For bcrypt, this is the cost for hashing the password and defaults to 10. If
# using other encryptors, it sets how many times you want the password re-encrypted.

View File

@@ -202,7 +202,7 @@ class ControllerAuthenticatableTest < ActionController::TestCase
test 'sign in and redirect uses the stored location' do
user = User.new
@controller.session[:"user_return_to"] = "/foo.bar"
@controller.session[:user_return_to] = "/foo.bar"
@mock_warden.expects(:user).with(:user).returns(nil)
@mock_warden.expects(:set_user).with(user, :scope => :user).returns(true)
@controller.expects(:redirect_to).with("/foo.bar")

View File

@@ -327,6 +327,20 @@ class AuthenticationSessionTest < ActionDispatch::IntegrationTest
assert_redirected_to new_user_session_path
end
test 'refreshes _csrf_token' do
ApplicationController.allow_forgery_protection = true
begin
get new_user_session_path
token = request.session[:_csrf_token]
sign_in_as_user
assert_not_equal request.session[:_csrf_token], token
ensure
ApplicationController.allow_forgery_protection = false
end
end
test 'allows session to be set for a given scope' do
sign_in_as_user
get '/users'
@@ -419,7 +433,7 @@ end
class AuthenticationOthersTest < ActionDispatch::IntegrationTest
test 'handles unverified requests gets rid of caches' do
swap UsersController, :allow_forgery_protection => true do
swap ApplicationController, :allow_forgery_protection => true do
post exhibit_user_url(1)
assert_not warden.authenticated?(:user)

View File

@@ -2,7 +2,7 @@ require 'test_helper'
class HttpAuthenticationTest < ActionDispatch::IntegrationTest
test 'handles unverified requests gets rid of caches but continues signed in' do
swap UsersController, :allow_forgery_protection => true do
swap ApplicationController, :allow_forgery_protection => true do
create_user
post exhibit_user_url(1), {}, "HTTP_AUTHORIZATION" => "Basic #{Base64.encode64("user@test.com:12345678")}"
assert warden.authenticated?(:user)

View File

@@ -30,8 +30,8 @@ class RememberMeTest < ActionDispatch::IntegrationTest
assert_nil request.cookies["remember_user_cookie"]
end
test 'handles unverified requests gets rid of caches' do
swap UsersController, :allow_forgery_protection => true do
test 'handle unverified requests gets rid of caches' do
swap ApplicationController, :allow_forgery_protection => true do
post exhibit_user_url(1)
assert_not warden.authenticated?(:user)
@@ -42,9 +42,21 @@ class RememberMeTest < ActionDispatch::IntegrationTest
end
end
test 'handle unverified requests does not create cookies on sign in' do
swap ApplicationController, :allow_forgery_protection => true do
get new_user_session_path
assert request.session[:_csrf_token]
post user_session_path, :authenticity_token => "oops", :user =>
{ :email => "jose.valim@gmail.com", :password => "123456", :remember_me => "1" }
assert_not warden.authenticated?(:user)
assert_not request.cookies['remember_user_token']
end
end
test 'generate remember token after sign in' do
sign_in_as_user :remember_me => true
assert request.cookies["remember_user_token"]
assert request.cookies['remember_user_token']
end
test 'generate remember token after sign in setting cookie options' do
@@ -90,16 +102,6 @@ class RememberMeTest < ActionDispatch::IntegrationTest
assert_redirected_to root_path
end
test 'cookies are destroyed on unverified requests' do
swap ApplicationController, :allow_forgery_protection => true do
create_user_and_remember
get users_path
assert warden.authenticated?(:user)
post root_path, :authenticity_token => 'INVALID'
assert_not warden.authenticated?(:user)
end
end
test 'does not extend remember period through sign in' do
swap Devise, :extend_remember_period => true, :remember_for => 1.year do
user = create_user