Decoding the Session Cookie: Rails 4.1

Posted: July 19, 2010. Tags: Rails

While trying to debug a "Request Header Or Cookie Too Large" error message from Nginx, I decided to decode my Rails session cookie to see what was in it.

First a word of caution about coping cookies our of browsers: If you're coping your cookie out of the Google Chrome Resources -> Cookies page, make sure you triple-click the cookie value before copying it (right-click and select Copy or Cmd-C on Mac OS X). If you just right click it and select Copy, it will only select the first "word" and you'll miss some necessary junk at the end of the cookie. Safari's Resources -> Cookies page has a "Copy Row" that is immune to this problem.

cookie = CGI.unescape(cookie)
config = Rails.application.config
secrets = Rails.application.secrets

encrypted_cookie_salt = config.action_dispatch.encrypted_cookie_salt               # "encrypted cookie" by default
encrypted_signed_cookie_salt = config.action_dispatch.encrypted_signed_cookie_salt # "signed encrypted cookie" by default

key_generator = ActiveSupport::KeyGenerator.new(secrets.secret_key_base, iterations: 1000)
secret = key_generator.generate_key(encrypted_cookie_salt)
sign_secret = key_generator.generate_key(encrypted_signed_cookie_salt)

encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret)
encryptor.decrypt_and_verify(cookie)

The above is based on this version but with the location of the secret_key_base fixed (it's in secrets now, not in app.config).

Here's some notes on how he figured it out:

# in Rails::Application.key_generator       railties/lib/rails/application.rb:153
key_generator = ActiveSupport::KeyGenerator.new(secrets.secret_key_base, iterations: 1000)

# in ActionDispatch::Cookies::EncryptedCookieJar.new        action_dispatch/middleware/cookies.rb:510
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, serializer: NullSerializer)

# in ActionDispatch::Cookies::EncryptedCookieJar#decrypt_and_verify     action_dispatch/middleware/cookies.rb:536
@encryptor.decrypt_and_verify(encrypted_message)