diff options
author | Assain <assainjaleel20@gmail.com> | 2018-05-19 13:31:57 +0530 |
---|---|---|
committer | Assain <assainjaleel20@gmail.com> | 2018-08-12 21:50:35 +0530 |
commit | 1cda4fb5df519080032c9c0a16d3c4f8cf1f3d2c (patch) | |
tree | 5e3b2acdd55627088a99e91494481645e365c35e /actionpack/lib | |
parent | ba1dab1e3b32a7c81cb9b8bdc22429f6620a3833 (diff) | |
download | rails-1cda4fb5df519080032c9c0a16d3c4f8cf1f3d2c.tar.gz rails-1cda4fb5df519080032c9c0a16d3c4f8cf1f3d2c.tar.bz2 rails-1cda4fb5df519080032c9c0a16d3c4f8cf1f3d2c.zip |
Purpose Metadata For Signed And Encrypted Cookies
Purpose metadata prevents cookie values from being
copy-pasted and ensures that the cookie is used only
for its originally intended purpose.
The Purpose and Expiry metadata are embedded inside signed/encrypted
cookies and will not be readable on previous versions of Rails.
We can switch off purpose and expiry metadata embedded in
signed and encrypted cookies using
config.action_dispatch.use_cookies_with_metadata = false
if you want your cookies to be readable on older versions of Rails.
Diffstat (limited to 'actionpack/lib')
-rw-r--r-- | actionpack/lib/action_dispatch/middleware/cookies.rb | 42 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/railtie.rb | 1 |
2 files changed, 30 insertions, 13 deletions
diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb index c45d947904..34331b7e4b 100644 --- a/actionpack/lib/action_dispatch/middleware/cookies.rb +++ b/actionpack/lib/action_dispatch/middleware/cookies.rb @@ -81,6 +81,10 @@ module ActionDispatch get_header Cookies::COOKIES_ROTATIONS end + def use_cookies_with_metadata + get_header Cookies::USE_COOKIES_WITH_METADATA + end + # :startdoc: end @@ -182,6 +186,7 @@ module ActionDispatch COOKIES_SERIALIZER = "action_dispatch.cookies_serializer".freeze COOKIES_DIGEST = "action_dispatch.cookies_digest".freeze COOKIES_ROTATIONS = "action_dispatch.cookies_rotations".freeze + USE_COOKIES_WITH_METADATA = "action_dispatch.use_cookies_with_metadata".freeze # Cookies can typically store 4096 bytes. MAX_COOKIE_SIZE = 4096 @@ -470,7 +475,7 @@ module ActionDispatch def [](name) if data = @parent_jar[name.to_s] - parse name, data + parse(name, data, purpose: "cookie.#{name}") || parse(name, data) end end @@ -481,7 +486,7 @@ module ActionDispatch options = { value: options } end - commit(options) + commit(name, options) @parent_jar[name] = options end @@ -497,13 +502,24 @@ module ActionDispatch end end - def parse(name, data); data; end - def commit(options); end + def cookie_metadata(name, options) + if request.use_cookies_with_metadata + metadata = expiry_options(options) + metadata[:purpose] = "cookie.#{name}" + + metadata + else + {} + end + end + + def parse(name, data, purpose: nil); data; end + def commit(name, options); end end class PermanentCookieJar < AbstractCookieJar # :nodoc: private - def commit(options) + def commit(name, options) options[:expires] = 20.years.from_now end end @@ -583,14 +599,14 @@ module ActionDispatch end private - def parse(name, signed_message) + def parse(name, signed_message, purpose: nil) deserialize(name) do |rotate| - @verifier.verified(signed_message, on_rotation: rotate) + @verifier.verified(signed_message, on_rotation: rotate, purpose: purpose) end end - def commit(options) - options[:value] = @verifier.generate(serialize(options[:value]), expiry_options(options)) + def commit(name, options) + options[:value] = @verifier.generate(serialize(options[:value]), cookie_metadata(name, options)) raise CookieOverflow if options[:value].bytesize > MAX_COOKIE_SIZE end @@ -631,16 +647,16 @@ module ActionDispatch end private - def parse(name, encrypted_message) + def parse(name, encrypted_message, purpose: nil) deserialize(name) do |rotate| - @encryptor.decrypt_and_verify(encrypted_message, on_rotation: rotate) + @encryptor.decrypt_and_verify(encrypted_message, on_rotation: rotate, purpose: purpose) end rescue ActiveSupport::MessageEncryptor::InvalidMessage, ActiveSupport::MessageVerifier::InvalidSignature parse_legacy_signed_message(name, encrypted_message) end - def commit(options) - options[:value] = @encryptor.encrypt_and_sign(serialize(options[:value]), expiry_options(options)) + def commit(name, options) + options[:value] = @encryptor.encrypt_and_sign(serialize(options[:value]), cookie_metadata(name, options)) raise CookieOverflow if options[:value].bytesize > MAX_COOKIE_SIZE end diff --git a/actionpack/lib/action_dispatch/railtie.rb b/actionpack/lib/action_dispatch/railtie.rb index eb6fbca6ba..efc3988bc3 100644 --- a/actionpack/lib/action_dispatch/railtie.rb +++ b/actionpack/lib/action_dispatch/railtie.rb @@ -21,6 +21,7 @@ module ActionDispatch config.action_dispatch.encrypted_signed_cookie_salt = "signed encrypted cookie" config.action_dispatch.authenticated_encrypted_cookie_salt = "authenticated encrypted cookie" config.action_dispatch.use_authenticated_cookie_encryption = false + config.action_dispatch.use_cookies_with_metadata = false config.action_dispatch.perform_deep_munge = true config.action_dispatch.default_headers = { |