Skip to content

Commit

Permalink
Allow users to change the default salt if they want, shouldn't be nec…
Browse files Browse the repository at this point in the history
…essary
  • Loading branch information
spastorino committed Nov 3, 2012
1 parent 5d23925 commit 47da574
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 21 deletions.
5 changes: 3 additions & 2 deletions actionpack/lib/action_controller/metal/http_authentication.rb
Expand Up @@ -249,8 +249,9 @@ def authentication_request(controller, realm, message = nil)
end

def secret_token(request)
key_generator = request.env["action_dispatch.key_generator"]
key_generator.generate_key('http authentication')
key_generator = request.env["action_dispatch.key_generator"]
http_auth_salt = request.env["action_dispatch.http_auth_salt"]
key_generator.generate_key(http_auth_salt)
end

# Uses an MD5 digest based on time to generate a value to be used only once.
Expand Down
33 changes: 22 additions & 11 deletions actionpack/lib/action_dispatch/middleware/cookies.rb
Expand Up @@ -82,6 +82,10 @@ def cookie_jar
class Cookies
HTTP_HEADER = "Set-Cookie".freeze
GENERATOR_KEY = "action_dispatch.key_generator".freeze
SIGNED_COOKIE_SALT = "action_dispatch.signed_cookie_salt".freeze
ENCRYPTED_COOKIE_SALT = "action_dispatch.encrypted_cookie_salt".freeze
ENCRYPTED_SIGNED_COOKIE_SALT = "action_dispatch.encrypted_signed_cookie_salt".freeze


# Raised when storing more than 4K of session data.
CookieOverflow = Class.new StandardError
Expand All @@ -106,21 +110,25 @@ class CookieJar #:nodoc:
def self.build(request)
env = request.env
key_generator = env[GENERATOR_KEY]
options = { signed_cookie_salt: env[SIGNED_COOKIE_SALT],
encrypted_cookie_salt: env[ENCRYPTED_COOKIE_SALT],
encrypted_signed_cookie_salt: env[ENCRYPTED_SIGNED_COOKIE_SALT] }

host = request.host
secure = request.ssl?

new(key_generator, host, secure).tap do |hash|
new(key_generator, host, secure, options).tap do |hash|
hash.update(request.cookies)
end
end

def initialize(key_generator, host = nil, secure = false)
def initialize(key_generator, host = nil, secure = false, options = {})
@key_generator = key_generator
@set_cookies = {}
@delete_cookies = {}
@host = host
@secure = secure
@options = options
@cookies = {}
end

Expand Down Expand Up @@ -223,7 +231,7 @@ def clear(options = {})
# cookies.permanent.signed[:remember_me] = current_user.id
# # => Set-Cookie: remember_me=BAhU--848956038e692d7046deab32b7131856ab20e14e; path=/; expires=Sun, 16-Dec-2029 03:24:16 GMT
def permanent
@permanent ||= PermanentCookieJar.new(self, @key_generator)
@permanent ||= PermanentCookieJar.new(self, @key_generator, @options)
end

# Returns a jar that'll automatically generate a signed representation of cookie value and verify it when reading from
Expand All @@ -240,7 +248,7 @@ def permanent
#
# cookies.signed[:discount] # => 45
def signed
@signed ||= SignedCookieJar.new(self, @key_generator)
@signed ||= SignedCookieJar.new(self, @key_generator, @options)
end

# Returns a jar that'll automatically encrypt cookie values before sending them to the client and will decrypt them for read.
Expand All @@ -256,7 +264,7 @@ def signed
#
# cookies.encrypted[:discount] # => 45
def encrypted
@encrypted ||= EncryptedCookieJar.new(self, @key_generator)
@encrypted ||= EncryptedCookieJar.new(self, @key_generator, @options)
end

def write(headers)
Expand All @@ -280,9 +288,10 @@ def write_cookie?(cookie)
end

class PermanentCookieJar < CookieJar #:nodoc:
def initialize(parent_jar, key_generator)
def initialize(parent_jar, key_generator, options = {})
@parent_jar = parent_jar
@key_generator = key_generator
@options = options
end

def []=(key, options)
Expand All @@ -305,9 +314,10 @@ class SignedCookieJar < CookieJar #:nodoc:
MAX_COOKIE_SIZE = 4096 # Cookies can typically store 4096 bytes.
SECRET_MIN_LENGTH = 30 # Characters

def initialize(parent_jar, key_generator)
def initialize(parent_jar, key_generator, options = {})
@parent_jar = parent_jar
secret = key_generator.generate_key('signed cookie')
@options = options
secret = key_generator.generate_key(@options[:signed_cookie_salt])
ensure_secret_secure(secret)
@verifier = ActiveSupport::MessageVerifier.new(secret)
end
Expand Down Expand Up @@ -359,10 +369,11 @@ def ensure_secret_secure(secret)
end

class EncryptedCookieJar < SignedCookieJar #:nodoc:
def initialize(parent_jar, key_generator)
def initialize(parent_jar, key_generator, options = {})
@parent_jar = parent_jar
secret = key_generator.generate_key('encrypted cookie')
sign_secret = key_generator.generate_key('signed encrypted cookie')
@options = options
secret = key_generator.generate_key(@options[:encrypted_cookie_salt])
sign_secret = key_generator.generate_key(@options[:encrypted_signed_cookie_salt])
@encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret)
ensure_secret_secure(secret)
end
Expand Down
4 changes: 4 additions & 0 deletions actionpack/lib/action_dispatch/railtie.rb
Expand Up @@ -13,6 +13,10 @@ class Railtie < Rails::Railtie
config.action_dispatch.rescue_responses = { }
config.action_dispatch.default_charset = nil
config.action_dispatch.rack_cache = false
config.action_dispatch.http_auth_salt = 'http authentication'
config.action_dispatch.signed_cookie_salt = 'signed cookie'
config.action_dispatch.encrypted_cookie_salt = 'encrypted cookie'
config.action_dispatch.encrypted_signed_cookie_salt = 'signed encrypted cookie'

config.action_dispatch.default_headers = {
'X-Frame-Options' => 'SAMEORIGIN',
Expand Down
5 changes: 4 additions & 1 deletion actionpack/test/dispatch/cookies_test.rb
Expand Up @@ -153,7 +153,10 @@ def noop

def setup
super
@request.env["action_dispatch.key_generator"] = ActiveSupport::DummyKeyGenerator.new("b3c631c314c0bbca50c1b2843150fe33")
@request.env["action_dispatch.key_generator"] = ActiveSupport::KeyGenerator.new("b3c631c314c0bbca50c1b2843150fe33")
@request.env["action_dispatch.signed_cookie_salt"] = "b3c631c314c0bbca50c1b2843150fe33"
@request.env["action_dispatch.encrypted_cookie_salt"] = "b3c631c314c0bbca50c1b2843150fe33"
@request.env["action_dispatch.encrypted_signed_cookie_salt"] = "b3c631c314c0bbca50c1b2843150fe33"
@request.host = "www.nextangle.com"
end

Expand Down
22 changes: 15 additions & 7 deletions railties/lib/rails/application.rb
Expand Up @@ -119,12 +119,16 @@ def key_generator
# will be used by middlewares and engines to configure themselves.
# Currently stores:
#
# * "action_dispatch.parameter_filter" => config.filter_parameters,
# * "action_dispatch.show_exceptions" => config.action_dispatch.show_exceptions,
# * "action_dispatch.show_detailed_exceptions" => config.consider_all_requests_local,
# * "action_dispatch.logger" => Rails.logger,
# * "action_dispatch.backtrace_cleaner" => Rails.backtrace_cleaner
# * "action_dispatch.key_generator" => key_generator
# * "action_dispatch.parameter_filter" => config.filter_parameters
# * "action_dispatch.show_exceptions" => config.action_dispatch.show_exceptions
# * "action_dispatch.show_detailed_exceptions" => config.consider_all_requests_local
# * "action_dispatch.logger" => Rails.logger
# * "action_dispatch.backtrace_cleaner" => Rails.backtrace_cleaner
# * "action_dispatch.key_generator" => key_generator
# * "action_dispatch.http_auth_salt" => config.action_dispatch.http_auth_salt
# * "action_dispatch.signed_cookie_salt" => config.action_dispatch.signed_cookie_salt
# * "action_dispatch.encrypted_cookie_salt" => config.action_dispatch.encrypted_cookie_salt
# * "action_dispatch.encrypted_signed_cookie_salt" => config.action_dispatch.encrypted_signed_cookie_salt
#
# These parameters will be used by middlewares and engines to configure themselves
#
Expand All @@ -145,7 +149,11 @@ def env_config
"action_dispatch.show_detailed_exceptions" => config.consider_all_requests_local,
"action_dispatch.logger" => Rails.logger,
"action_dispatch.backtrace_cleaner" => Rails.backtrace_cleaner,
"action_dispatch.key_generator" => key_generator
"action_dispatch.key_generator" => key_generator,
"action_dispatch.http_auth_salt" => config.action_dispatch.http_auth_salt,
"action_dispatch.signed_cookie_salt" => config.action_dispatch.signed_cookie_salt,
"action_dispatch.encrypted_cookie_salt" => config.action_dispatch.encrypted_cookie_salt,
"action_dispatch.encrypted_signed_cookie_salt" => config.action_dispatch.encrypted_signed_cookie_salt
})
end
end
Expand Down

0 comments on commit 47da574

Please sign in to comment.