2012-01-12 14:46:54 -05:00
|
|
|
# encoding: utf-8
|
|
|
|
require 'isolation/abstract_unit'
|
|
|
|
require 'rack/test'
|
|
|
|
|
|
|
|
module ApplicationTests
|
|
|
|
class MiddlewareSessionTest < ActiveSupport::TestCase
|
|
|
|
include ActiveSupport::Testing::Isolation
|
|
|
|
include Rack::Test::Methods
|
|
|
|
|
|
|
|
def setup
|
|
|
|
build_app
|
|
|
|
boot_rails
|
|
|
|
FileUtils.rm_rf "#{app_path}/config/environments"
|
|
|
|
end
|
|
|
|
|
|
|
|
def teardown
|
|
|
|
teardown_app
|
|
|
|
end
|
|
|
|
|
|
|
|
def app
|
|
|
|
@app ||= Rails.application
|
|
|
|
end
|
|
|
|
|
|
|
|
test "config.force_ssl sets cookie to secure only" do
|
|
|
|
add_to_config "config.force_ssl = true"
|
|
|
|
require "#{app_path}/config/environment"
|
|
|
|
assert app.config.session_options[:secure], "Expected session to be marked as secure"
|
|
|
|
end
|
2012-04-30 02:36:39 -04:00
|
|
|
|
|
|
|
test "session is not loaded if it's not used" do
|
|
|
|
make_basic_app
|
|
|
|
|
|
|
|
class ::OmgController < ActionController::Base
|
|
|
|
def index
|
|
|
|
if params[:flash]
|
|
|
|
flash[:notice] = "notice"
|
|
|
|
end
|
|
|
|
|
2012-10-14 06:03:39 -04:00
|
|
|
render nothing: true
|
2012-04-30 02:36:39 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
get "/?flash=true"
|
|
|
|
get "/"
|
|
|
|
|
|
|
|
assert last_request.env["HTTP_COOKIE"]
|
|
|
|
assert !last_response.headers["Set-Cookie"]
|
|
|
|
end
|
2012-09-13 05:07:37 -04:00
|
|
|
|
|
|
|
test "session is empty and isn't saved on unverified request when using :null_session protect method" do
|
|
|
|
app_file 'config/routes.rb', <<-RUBY
|
2013-06-03 23:57:01 -04:00
|
|
|
Rails.application.routes.draw do
|
2012-09-13 05:07:37 -04:00
|
|
|
get ':controller(/:action)'
|
|
|
|
post ':controller(/:action)'
|
|
|
|
end
|
|
|
|
RUBY
|
|
|
|
|
|
|
|
controller :foo, <<-RUBY
|
|
|
|
class FooController < ActionController::Base
|
|
|
|
protect_from_forgery with: :null_session
|
|
|
|
|
|
|
|
def write_session
|
|
|
|
session[:foo] = 1
|
|
|
|
render nothing: true
|
|
|
|
end
|
|
|
|
|
|
|
|
def read_session
|
|
|
|
render text: session[:foo].inspect
|
|
|
|
end
|
|
|
|
end
|
|
|
|
RUBY
|
|
|
|
|
|
|
|
add_to_config <<-RUBY
|
|
|
|
config.action_controller.allow_forgery_protection = true
|
|
|
|
RUBY
|
|
|
|
|
|
|
|
require "#{app_path}/config/environment"
|
|
|
|
|
|
|
|
get '/foo/write_session'
|
|
|
|
get '/foo/read_session'
|
|
|
|
assert_equal '1', last_response.body
|
|
|
|
|
|
|
|
post '/foo/read_session' # Read session using POST request without CSRF token
|
|
|
|
assert_equal 'nil', last_response.body # Stored value shouldn't be accessible
|
|
|
|
|
|
|
|
post '/foo/write_session' # Write session using POST request without CSRF token
|
|
|
|
get '/foo/read_session' # Session shouldn't be changed
|
|
|
|
assert_equal '1', last_response.body
|
|
|
|
end
|
|
|
|
|
|
|
|
test "cookie jar is empty and isn't saved on unverified request when using :null_session protect method" do
|
|
|
|
app_file 'config/routes.rb', <<-RUBY
|
2013-06-03 23:57:01 -04:00
|
|
|
Rails.application.routes.draw do
|
2012-09-13 05:07:37 -04:00
|
|
|
get ':controller(/:action)'
|
|
|
|
post ':controller(/:action)'
|
|
|
|
end
|
|
|
|
RUBY
|
|
|
|
|
|
|
|
controller :foo, <<-RUBY
|
|
|
|
class FooController < ActionController::Base
|
|
|
|
protect_from_forgery with: :null_session
|
|
|
|
|
|
|
|
def write_cookie
|
|
|
|
cookies[:foo] = '1'
|
|
|
|
render nothing: true
|
|
|
|
end
|
|
|
|
|
|
|
|
def read_cookie
|
|
|
|
render text: cookies[:foo].inspect
|
|
|
|
end
|
|
|
|
end
|
|
|
|
RUBY
|
|
|
|
|
|
|
|
add_to_config <<-RUBY
|
|
|
|
config.action_controller.allow_forgery_protection = true
|
|
|
|
RUBY
|
|
|
|
|
|
|
|
require "#{app_path}/config/environment"
|
|
|
|
|
|
|
|
get '/foo/write_cookie'
|
|
|
|
get '/foo/read_cookie'
|
|
|
|
assert_equal '"1"', last_response.body
|
|
|
|
|
|
|
|
post '/foo/read_cookie' # Read cookie using POST request without CSRF token
|
|
|
|
assert_equal 'nil', last_response.body # Stored value shouldn't be accessible
|
|
|
|
|
|
|
|
post '/foo/write_cookie' # Write cookie using POST request without CSRF token
|
|
|
|
get '/foo/read_cookie' # Cookie shouldn't be changed
|
|
|
|
assert_equal '"1"', last_response.body
|
|
|
|
end
|
2012-10-30 16:12:23 -04:00
|
|
|
|
|
|
|
test "session using encrypted cookie store" do
|
|
|
|
app_file 'config/routes.rb', <<-RUBY
|
2013-06-03 23:57:01 -04:00
|
|
|
Rails.application.routes.draw do
|
2012-10-30 16:12:23 -04:00
|
|
|
get ':controller(/:action)'
|
|
|
|
end
|
|
|
|
RUBY
|
|
|
|
|
|
|
|
controller :foo, <<-RUBY
|
|
|
|
class FooController < ActionController::Base
|
|
|
|
def write_session
|
|
|
|
session[:foo] = 1
|
|
|
|
render nothing: true
|
|
|
|
end
|
|
|
|
|
|
|
|
def read_session
|
|
|
|
render text: session[:foo]
|
|
|
|
end
|
|
|
|
|
|
|
|
def read_encrypted_cookie
|
|
|
|
render text: cookies.encrypted[:_myapp_session]['foo']
|
|
|
|
end
|
|
|
|
|
|
|
|
def read_raw_cookie
|
|
|
|
render text: cookies[:_myapp_session]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
RUBY
|
|
|
|
|
|
|
|
require "#{app_path}/config/environment"
|
|
|
|
|
|
|
|
get '/foo/write_session'
|
|
|
|
get '/foo/read_session'
|
|
|
|
assert_equal '1', last_response.body
|
|
|
|
|
|
|
|
get '/foo/read_encrypted_cookie'
|
|
|
|
assert_equal '1', last_response.body
|
|
|
|
|
|
|
|
secret = app.key_generator.generate_key('encrypted cookie')
|
|
|
|
sign_secret = app.key_generator.generate_key('signed encrypted cookie')
|
|
|
|
encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret)
|
|
|
|
|
|
|
|
get '/foo/read_raw_cookie'
|
|
|
|
assert_equal 1, encryptor.decrypt_and_verify(last_response.body)['foo']
|
|
|
|
end
|
2012-11-16 14:17:08 -05:00
|
|
|
|
2013-03-28 15:35:48 -04:00
|
|
|
test "session upgrading signature to encryption cookie store works the same way as encrypted cookie store" do
|
2012-11-16 14:17:08 -05:00
|
|
|
app_file 'config/routes.rb', <<-RUBY
|
2013-06-03 23:57:01 -04:00
|
|
|
Rails.application.routes.draw do
|
2012-11-16 14:17:08 -05:00
|
|
|
get ':controller(/:action)'
|
|
|
|
end
|
|
|
|
RUBY
|
|
|
|
|
|
|
|
controller :foo, <<-RUBY
|
|
|
|
class FooController < ActionController::Base
|
|
|
|
def write_session
|
|
|
|
session[:foo] = 1
|
|
|
|
render nothing: true
|
|
|
|
end
|
|
|
|
|
|
|
|
def read_session
|
|
|
|
render text: session[:foo]
|
|
|
|
end
|
|
|
|
|
|
|
|
def read_encrypted_cookie
|
|
|
|
render text: cookies.encrypted[:_myapp_session]['foo']
|
|
|
|
end
|
|
|
|
|
|
|
|
def read_raw_cookie
|
|
|
|
render text: cookies[:_myapp_session]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
RUBY
|
|
|
|
|
|
|
|
add_to_config <<-RUBY
|
2014-10-27 13:04:37 -04:00
|
|
|
secrets.secret_token = "3b7cd727ee24e8444053437c36cc66c4"
|
2012-11-16 14:17:08 -05:00
|
|
|
RUBY
|
|
|
|
|
|
|
|
require "#{app_path}/config/environment"
|
|
|
|
|
|
|
|
get '/foo/write_session'
|
|
|
|
get '/foo/read_session'
|
|
|
|
assert_equal '1', last_response.body
|
|
|
|
|
|
|
|
get '/foo/read_encrypted_cookie'
|
|
|
|
assert_equal '1', last_response.body
|
|
|
|
|
|
|
|
secret = app.key_generator.generate_key('encrypted cookie')
|
|
|
|
sign_secret = app.key_generator.generate_key('signed encrypted cookie')
|
|
|
|
encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret)
|
|
|
|
|
|
|
|
get '/foo/read_raw_cookie'
|
|
|
|
assert_equal 1, encryptor.decrypt_and_verify(last_response.body)['foo']
|
|
|
|
end
|
|
|
|
|
2013-03-28 15:35:48 -04:00
|
|
|
test "session upgrading signature to encryption cookie store upgrades session to encrypted mode" do
|
2012-11-16 14:17:08 -05:00
|
|
|
app_file 'config/routes.rb', <<-RUBY
|
2013-06-03 23:57:01 -04:00
|
|
|
Rails.application.routes.draw do
|
2012-11-16 14:17:08 -05:00
|
|
|
get ':controller(/:action)'
|
|
|
|
end
|
|
|
|
RUBY
|
|
|
|
|
|
|
|
controller :foo, <<-RUBY
|
|
|
|
class FooController < ActionController::Base
|
|
|
|
def write_raw_session
|
|
|
|
# {"session_id"=>"1965d95720fffc123941bdfb7d2e6870", "foo"=>1}
|
|
|
|
cookies[:_myapp_session] = "BAh7B0kiD3Nlc3Npb25faWQGOgZFRkkiJTE5NjVkOTU3MjBmZmZjMTIzOTQxYmRmYjdkMmU2ODcwBjsAVEkiCGZvbwY7AEZpBg==--315fb9931921a87ae7421aec96382f0294119749"
|
|
|
|
render nothing: true
|
|
|
|
end
|
|
|
|
|
|
|
|
def write_session
|
|
|
|
session[:foo] = session[:foo] + 1
|
|
|
|
render nothing: true
|
|
|
|
end
|
|
|
|
|
|
|
|
def read_session
|
|
|
|
render text: session[:foo]
|
|
|
|
end
|
|
|
|
|
|
|
|
def read_encrypted_cookie
|
|
|
|
render text: cookies.encrypted[:_myapp_session]['foo']
|
|
|
|
end
|
|
|
|
|
|
|
|
def read_raw_cookie
|
|
|
|
render text: cookies[:_myapp_session]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
RUBY
|
|
|
|
|
|
|
|
add_to_config <<-RUBY
|
2014-10-27 13:04:37 -04:00
|
|
|
secrets.secret_token = "3b7cd727ee24e8444053437c36cc66c4"
|
2012-11-16 14:17:08 -05:00
|
|
|
RUBY
|
|
|
|
|
|
|
|
require "#{app_path}/config/environment"
|
|
|
|
|
|
|
|
get '/foo/write_raw_session'
|
|
|
|
get '/foo/read_session'
|
|
|
|
assert_equal '1', last_response.body
|
|
|
|
|
|
|
|
get '/foo/write_session'
|
|
|
|
get '/foo/read_session'
|
|
|
|
assert_equal '2', last_response.body
|
|
|
|
|
|
|
|
get '/foo/read_encrypted_cookie'
|
|
|
|
assert_equal '2', last_response.body
|
|
|
|
|
|
|
|
secret = app.key_generator.generate_key('encrypted cookie')
|
|
|
|
sign_secret = app.key_generator.generate_key('signed encrypted cookie')
|
|
|
|
encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret)
|
|
|
|
|
|
|
|
get '/foo/read_raw_cookie'
|
|
|
|
assert_equal 2, encryptor.decrypt_and_verify(last_response.body)['foo']
|
|
|
|
end
|
2013-03-28 15:35:48 -04:00
|
|
|
|
|
|
|
test "session upgrading legacy signed cookies to new signed cookies" do
|
|
|
|
app_file 'config/routes.rb', <<-RUBY
|
2013-06-03 23:57:01 -04:00
|
|
|
Rails.application.routes.draw do
|
2013-03-28 15:35:48 -04:00
|
|
|
get ':controller(/:action)'
|
|
|
|
end
|
|
|
|
RUBY
|
|
|
|
|
|
|
|
controller :foo, <<-RUBY
|
|
|
|
class FooController < ActionController::Base
|
|
|
|
def write_raw_session
|
|
|
|
# {"session_id"=>"1965d95720fffc123941bdfb7d2e6870", "foo"=>1}
|
|
|
|
cookies[:_myapp_session] = "BAh7B0kiD3Nlc3Npb25faWQGOgZFRkkiJTE5NjVkOTU3MjBmZmZjMTIzOTQxYmRmYjdkMmU2ODcwBjsAVEkiCGZvbwY7AEZpBg==--315fb9931921a87ae7421aec96382f0294119749"
|
|
|
|
render nothing: true
|
|
|
|
end
|
|
|
|
|
|
|
|
def write_session
|
|
|
|
session[:foo] = session[:foo] + 1
|
|
|
|
render nothing: true
|
|
|
|
end
|
|
|
|
|
|
|
|
def read_session
|
|
|
|
render text: session[:foo]
|
|
|
|
end
|
|
|
|
|
|
|
|
def read_signed_cookie
|
|
|
|
render text: cookies.signed[:_myapp_session]['foo']
|
|
|
|
end
|
|
|
|
|
|
|
|
def read_raw_cookie
|
|
|
|
render text: cookies[:_myapp_session]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
RUBY
|
|
|
|
|
|
|
|
add_to_config <<-RUBY
|
2014-10-27 13:04:37 -04:00
|
|
|
secrets.secret_token = "3b7cd727ee24e8444053437c36cc66c4"
|
2013-12-12 11:07:31 -05:00
|
|
|
secrets.secret_key_base = nil
|
2013-03-28 15:35:48 -04:00
|
|
|
RUBY
|
|
|
|
|
|
|
|
require "#{app_path}/config/environment"
|
|
|
|
|
|
|
|
get '/foo/write_raw_session'
|
|
|
|
get '/foo/read_session'
|
|
|
|
assert_equal '1', last_response.body
|
|
|
|
|
|
|
|
get '/foo/write_session'
|
|
|
|
get '/foo/read_session'
|
|
|
|
assert_equal '2', last_response.body
|
|
|
|
|
|
|
|
get '/foo/read_signed_cookie'
|
|
|
|
assert_equal '2', last_response.body
|
|
|
|
|
2014-10-27 13:04:37 -04:00
|
|
|
verifier = ActiveSupport::MessageVerifier.new(app.secrets.secret_token)
|
2013-03-28 15:35:48 -04:00
|
|
|
|
|
|
|
get '/foo/read_raw_cookie'
|
|
|
|
assert_equal 2, verifier.verify(last_response.body)['foo']
|
|
|
|
end
|
2012-01-12 14:46:54 -05:00
|
|
|
end
|
|
|
|
end
|