From 60609bb50d5b99d78a01a945a539cccd061cd7e7 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 31 Oct 2012 01:06:46 -0200 Subject: Sign cookies using key deriver --- activesupport/lib/active_support/key_generator.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'activesupport') diff --git a/activesupport/lib/active_support/key_generator.rb b/activesupport/lib/active_support/key_generator.rb index 04d170f801..8b49ad8414 100644 --- a/activesupport/lib/active_support/key_generator.rb +++ b/activesupport/lib/active_support/key_generator.rb @@ -20,4 +20,14 @@ module ActiveSupport OpenSSL::PKCS5.pbkdf2_hmac_sha1(@secret, salt, @iterations, key_size) end end + + class DummyKeyGenerator + def initialize(secret) + @secret = secret + end + + def generate_key(salt) + @secret + end + end end -- cgit v1.2.3 From 38c40dbbc1de5837a05d762be95e69105acc929c Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 30 Oct 2012 16:41:11 -0200 Subject: Add cookie.encrypted which returns an EncryptedCookieJar How to use it? cookies.encrypted[:discount] = 45 => Set-Cookie: discount=ZS9ZZ1R4cG1pcUJ1bm80anhQang3dz09LS1mbDZDSU5scGdOT3ltQ2dTdlhSdWpRPT0%3D--ab54663c9f4e3bc340c790d6d2b71e92f5b60315; path=/ cookies.encrypted[:discount] => 45 --- activesupport/lib/active_support/message_encryptor.rb | 7 +++++-- activesupport/test/message_encryptor_test.rb | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'activesupport') diff --git a/activesupport/lib/active_support/message_encryptor.rb b/activesupport/lib/active_support/message_encryptor.rb index 580267708c..1588674afc 100644 --- a/activesupport/lib/active_support/message_encryptor.rb +++ b/activesupport/lib/active_support/message_encryptor.rb @@ -39,10 +39,13 @@ module ActiveSupport # * :cipher - Cipher to use. Can be any cipher returned by # OpenSSL::Cipher.ciphers. Default is 'aes-256-cbc'. # * :serializer - Object serializer to use. Default is +Marshal+. - def initialize(secret, options = {}) + def initialize(secret, *signature_key_or_options) + options = signature_key_or_options.extract_options! + sign_secret = signature_key_or_options.first @secret = secret + @sign_secret = sign_secret @cipher = options[:cipher] || 'aes-256-cbc' - @verifier = MessageVerifier.new(@secret, :serializer => NullSerializer) + @verifier = MessageVerifier.new(@sign_secret || @secret, :serializer => NullSerializer) @serializer = options[:serializer] || Marshal end diff --git a/activesupport/test/message_encryptor_test.rb b/activesupport/test/message_encryptor_test.rb index b544742300..d6c31396b6 100644 --- a/activesupport/test/message_encryptor_test.rb +++ b/activesupport/test/message_encryptor_test.rb @@ -56,7 +56,7 @@ class MessageEncryptorTest < ActiveSupport::TestCase end def test_alternative_serialization_method - encryptor = ActiveSupport::MessageEncryptor.new(SecureRandom.hex(64), :serializer => JSONSerializer.new) + encryptor = ActiveSupport::MessageEncryptor.new(SecureRandom.hex(64), SecureRandom.hex(64), :serializer => JSONSerializer.new) message = encryptor.encrypt_and_sign({ :foo => 123, 'bar' => Time.utc(2010) }) assert_equal encryptor.decrypt_and_verify(message), { "foo" => 123, "bar" => "2010-01-01T00:00:00Z" } end -- cgit v1.2.3 From 851e8fe897633f095a0f39a91f8bc75eee7a76aa Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Thu, 1 Nov 2012 20:23:21 -0200 Subject: Cache generated keys per KeyGenerator instance using salt + key_size --- activesupport/lib/active_support/key_generator.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'activesupport') diff --git a/activesupport/lib/active_support/key_generator.rb b/activesupport/lib/active_support/key_generator.rb index 8b49ad8414..a8a4c17fd6 100644 --- a/activesupport/lib/active_support/key_generator.rb +++ b/activesupport/lib/active_support/key_generator.rb @@ -1,3 +1,4 @@ +require 'mutex_m' require 'openssl' module ActiveSupport @@ -21,6 +22,19 @@ module ActiveSupport end end + class CachingKeyGenerator + def initialize(key_generator) + @key_generator = key_generator + @cache_keys = {}.extend(Mutex_m) + end + + def generate_key(salt, key_size=64) + @cache_keys.synchronize do + @cache_keys["#{salt}#{key_size}"] ||= @key_generator.generate_key(salt, key_size) + end + end + end + class DummyKeyGenerator def initialize(secret) @secret = secret -- cgit v1.2.3 From c2a7956eb7fbc099ea38d21601d215ab3def27fb Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 2 Nov 2012 11:03:18 -0200 Subject: Move ensure_secret_secure to DummyKeyGenerator --- activesupport/lib/active_support/key_generator.rb | 24 +++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'activesupport') diff --git a/activesupport/lib/active_support/key_generator.rb b/activesupport/lib/active_support/key_generator.rb index a8a4c17fd6..2b5a6fa0ba 100644 --- a/activesupport/lib/active_support/key_generator.rb +++ b/activesupport/lib/active_support/key_generator.rb @@ -36,12 +36,36 @@ module ActiveSupport end class DummyKeyGenerator + SECRET_MIN_LENGTH = 30 # Characters + def initialize(secret) + ensure_secret_secure(secret) @secret = secret end def generate_key(salt) @secret end + + private + + # To prevent users from using something insecure like "Password" we make sure that the + # secret they've provided is at least 30 characters in length. + def ensure_secret_secure(secret) + if secret.blank? + raise ArgumentError, "A secret is required to generate an " + + "integrity hash for cookie session data. Use " + + "config.secret_token_key = \"some secret phrase of at " + + "least #{SECRET_MIN_LENGTH} characters\"" + + "in config/initializers/secret_token.rb" + end + + if secret.length < SECRET_MIN_LENGTH + raise ArgumentError, "Secret should be something secure, " + + "like \"#{SecureRandom.hex(16)}\". The value you " + + "provided, \"#{secret}\", is shorter than the minimum length " + + "of #{SECRET_MIN_LENGTH} characters" + end + end end end -- cgit v1.2.3 From 4faa0418453055bc81456685d418d486252cc379 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 2 Nov 2012 20:27:51 -0200 Subject: Rename secret_token_key to secret_key_base --- activesupport/lib/active_support/key_generator.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activesupport') diff --git a/activesupport/lib/active_support/key_generator.rb b/activesupport/lib/active_support/key_generator.rb index 2b5a6fa0ba..2c8fccec7d 100644 --- a/activesupport/lib/active_support/key_generator.rb +++ b/activesupport/lib/active_support/key_generator.rb @@ -55,7 +55,7 @@ module ActiveSupport if secret.blank? raise ArgumentError, "A secret is required to generate an " + "integrity hash for cookie session data. Use " + - "config.secret_token_key = \"some secret phrase of at " + + "config.secret_key_base = \"some secret phrase of at " + "least #{SECRET_MIN_LENGTH} characters\"" + "in config/initializers/secret_token.rb" end -- cgit v1.2.3