Skip to content

Instantly share code, notes, and snippets.

@pdfrod
Forked from profh/decode_session_cookie.rb
Last active March 25, 2022 15:15
Show Gist options
  • Star 16 You must be signed in to star a gist
  • Fork 18 You must be signed in to fork a gist
  • Save pdfrod/9c3b6b6f9aa1dc4726a5 to your computer and use it in GitHub Desktop.
Save pdfrod/9c3b6b6f9aa1dc4726a5 to your computer and use it in GitHub Desktop.
A simple script to decode Rails 4 session cookies
@jordan-brough
Copy link

This worked for me except that I didn't need the Marshal.load. It blew up with:

TypeError: incompatible marshal file format (can't be read)

The rest worked.

Also FYI the key_size variable is unused.

@nvanexan
Copy link

I'm also getting ActiveSupport::MessageVerifier::InvalidSignature exception.

Using Rails 4.2.2.

I'm calling the method as follows:

decrypt_session_cookie(params["session_id"], ENV["SECRET_KEY_BASE"])

Where params["session_id"] is the cookie value being passed via ajax from a chrome extension to my app.

Any thoughts? Thanks in advance!

@timscott
Copy link

Same experience as @jordan-brough. I removed Marshal.load and it worked.

@robvandijk
Copy link

@nvanexan, did you manage to get rid of the ActiveSupport::MessageVerifier::InvalidSignature exception? I also get this exception...

@robvandijk
Copy link

Never mind @nvanexan, just figured it out. Had secret_key_base set both in a secrets.yml and in secret_token.rb, with different values, causing the confusion...

@smoyte
Copy link

smoyte commented Jan 19, 2017

For some strange reason when I tried to copy the key from Chrome it was not copying anything after the -- at the end, and that was giving me the exception above. I ended up having to type the last 32 chars by hand! Then it worked.

@talyric
Copy link

talyric commented Mar 30, 2017

@robvandijk Thanks for posting about "secret_key_base set both in a secrets.yml and in secret_token.rb". That was just the clue I needed to solve a problem!

@jwg2s
Copy link

jwg2s commented Sep 19, 2018

For anyone else who stumbles upon this, here's the updated script to actually use the key_size variable:

require 'rubygems'
require 'cgi'
require 'active_support'
require 'action_controller'

def decrypt_session_cookie(cookie, key)
  cookie = CGI::unescape(cookie)

  # Default values for Rails 5 apps
  key_iter_num = 1000
  key_size     = 32
  salt         = "encrypted cookie"
  signed_salt  = "signed encrypted cookie"

  key_generator = ActiveSupport::KeyGenerator.new(key, iterations: key_iter_num)
  secret = key_generator.generate_key(salt)[0..key_size-1]
  sign_secret = key_generator.generate_key(signed_salt)

  encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret, serializer: ActiveSupport::MessageEncryptor::NullSerializer)
  puts encryptor.decrypt_and_verify(cookie)
end

cookie = 'WUtLMGhlSlovNjh0ZG83OThCdzdUZDFETEhRSEUrU2cwQlB0K1JZNTNUVkRGMUs3ZUw0UmdNL3dvUnZNNzA2RmVxbk96Y0lJUTh1WnJHNE1nbnk1OCtuNEFQeTN4M0Y5OGlobkVXWTFzfaopef9RVTV1UnM4eTRIV09VQ1Y3RzNLT0pWd2hZQ3JnQnlRNHhUckRlakxlNkozQmZNbWNnYnZ3enA1b1Y0RjB4YnJyVEdMWkFOUGxiVEdmSkdsZ3NDOU84MnpZdE5LdFZRdkM1NVBjZWxmZURXY2lpTmFoMXJ6TnJzSk44NkFWcm9vdE0rV213YmMwbDVKWldrVldPbFl3V2ovS3BSRFRkaDc5TllXc0lKZVNmQ3c9PS0tT1ZCWXVoNzVreUJMWUZIdkp3QW5iQT09--fc7bfe14e7cc19c625b416e8e4bde934959bd791'
key = Rails.application.secrets.secret_key_base

decrypt_session_cookie(cookie, key)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment