lib/action_controller/session/cookie_store.rb in actionpack-2.0.5 vs lib/action_controller/session/cookie_store.rb in actionpack-2.1.0
- old
+ new
@@ -12,31 +12,31 @@
#
# CookieOverflow is raised if you attempt to store more than 4K of data.
# TamperedWithCookie is raised if the data integrity check fails.
#
# A message digest is included with the cookie to ensure data integrity:
-# a user cannot alter his user_id without knowing the secret key included in
+# a user cannot alter his +user_id+ without knowing the secret key included in
# the hash. New apps are generated with a pregenerated secret in
# config/environment.rb. Set your own for old apps you're upgrading.
#
# Session options:
-# :secret An application-wide key string or block returning a string
-# called per generated digest. The block is called with the
-# CGI::Session instance as an argument. It's important that the
-# secret is not vulnerable to a dictionary attack. Therefore,
-# you should choose a secret consisting of random numbers and
-# letters and more than 30 characters.
#
-# Example: :secret => '449fe2e7daee471bffae2fd8dc02313d'
-# :secret => Proc.new { User.current_user.secret_key }
+# * <tt>:secret</tt>: An application-wide key string or block returning a string
+# called per generated digest. The block is called with the CGI::Session
+# instance as an argument. It's important that the secret is not vulnerable to
+# a dictionary attack. Therefore, you should choose a secret consisting of
+# random numbers and letters and more than 30 characters. Examples:
#
-# :digest The message digest algorithm used to verify session integrity
-# defaults to 'SHA1' but may be any digest provided by OpenSSL,
-# such as 'MD5', 'RIPEMD160', 'SHA256', etc.
+# :secret => '449fe2e7daee471bffae2fd8dc02313d'
+# :secret => Proc.new { User.current_user.secret_key }
#
+# * <tt>:digest</tt>: The message digest algorithm used to verify session
+# integrity defaults to 'SHA1' but may be any digest provided by OpenSSL,
+# such as 'MD5', 'RIPEMD160', 'SHA256', etc.
+#
# To generate a secret key for an existing application, run
-# `rake secret` and set the key in config/environment.rb
+# "rake secret" and set the key in config/environment.rb.
#
# Note that changing digest or secret invalidates all existing sessions!
class CGI::Session::CookieStore
# Cookies can typically store 4096 bytes.
MAX = 4096
@@ -115,11 +115,11 @@
# Delete the session data by setting an expired cookie with no data.
def delete
@data = nil
clear_old_cookie_value
- write_cookie('value' => '', 'expires' => 1.year.ago)
+ write_cookie('value' => nil, 'expires' => 1.year.ago)
end
# Generate the HMAC keyed message digest. Uses SHA1 by default.
def generate_digest(data)
key = @secret.respond_to?(:call) ? @secret.call(@session) : @secret
@@ -128,20 +128,23 @@
private
# Marshal a session hash into safe cookie data. Include an integrity hash.
def marshal(session)
data = ActiveSupport::Base64.encode64(Marshal.dump(session)).chop
- CGI.escape "#{data}--#{generate_digest(data)}"
+ "#{data}--#{generate_digest(data)}"
end
# Unmarshal cookie data to a hash and verify its integrity.
def unmarshal(cookie)
if cookie
- data, digest = CGI.unescape(cookie).split('--')
- unless digest == generate_digest(data)
+ data, digest = cookie.split('--')
+
+ # Do two checks to transparently support old double-escaped data.
+ unless digest == generate_digest(data) || digest == generate_digest(data = CGI.unescape(data))
delete
raise TamperedWithCookie
end
+
Marshal.load(ActiveSupport::Base64.decode64(data))
end
end
# Read the session data cookie.