diff options
author | José Valim <jose.valim@gmail.com> | 2010-05-18 01:43:06 +0200 |
---|---|---|
committer | José Valim <jose.valim@gmail.com> | 2010-05-18 02:05:20 +0200 |
commit | 25f7c030e4ea440ea6c2a84c92118299753392d9 (patch) | |
tree | e2c1168b9342db55a982c2452b46ff5999e59394 /actionpack/lib/action_dispatch/middleware/cookies.rb | |
parent | 941b653627b9ca7b7f2ddb4a712fb0efccc10500 (diff) | |
download | rails-25f7c030e4ea440ea6c2a84c92118299753392d9.tar.gz rails-25f7c030e4ea440ea6c2a84c92118299753392d9.tar.bz2 rails-25f7c030e4ea440ea6c2a84c92118299753392d9.zip |
Simplify cookie_store by simply relying on cookies.signed.
Diffstat (limited to 'actionpack/lib/action_dispatch/middleware/cookies.rb')
-rw-r--r-- | actionpack/lib/action_dispatch/middleware/cookies.rb | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb index 42ab1d1ebb..1e49a307ed 100644 --- a/actionpack/lib/action_dispatch/middleware/cookies.rb +++ b/actionpack/lib/action_dispatch/middleware/cookies.rb @@ -52,6 +52,9 @@ module ActionDispatch # * <tt>:httponly</tt> - Whether this cookie is accessible via scripting or # only HTTP. Defaults to +false+. class Cookies + # Raised when storing more than 4K of session data. + class CookieOverflow < StandardError; end + class CookieJar < Hash #:nodoc: def self.build(request) secret = request.env["action_dispatch.secret_token"] @@ -166,8 +169,11 @@ module ActionDispatch end class SignedCookieJar < CookieJar #:nodoc: + MAX_COOKIE_SIZE = 4096 # Cookies can typically store 4096 bytes. + SECRET_MIN_LENGTH = 30 # Characters + def initialize(parent_jar, secret) - raise "You must set config.secret_token in your app's config" if secret.blank? + ensure_secret_secure(secret) @parent_jar = parent_jar @verifier = ActiveSupport::MessageVerifier.new(secret) end @@ -176,6 +182,8 @@ module ActionDispatch if signed_message = @parent_jar[name] @verifier.verify(signed_message) end + rescue ActiveSupport::MessageVerifier::InvalidSignature + nil end def []=(key, options) @@ -186,12 +194,34 @@ module ActionDispatch options = { :value => @verifier.generate(options) } end + raise CookieOverflow if options[:value].size > MAX_COOKIE_SIZE @parent_jar[key] = options end def method_missing(method, *arguments, &block) @parent_jar.send(method, *arguments, &block) end + + protected + + # 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 = \"some secret phrase of at " + + "least #{SECRET_MIN_LENGTH} characters\"" + + "in config/application.rb" + end + + if secret.length < SECRET_MIN_LENGTH + raise ArgumentError, "Secret should be something secure, " + + "like \"#{ActiveSupport::SecureRandom.hex(16)}\". The value you " + + "provided, \"#{secret}\", is shorter than the minimum length " + + "of #{SECRET_MIN_LENGTH} characters" + end + end end def initialize(app) |