Read more

Rails: Decrypt a session cookie

Emanuel
October 28, 2019Software engineer at makandra GmbH

This method helps you to manually decrypt the session cookie in Rails 5.2. Chrome can retrieve the session cookie string from Dev Tools > Application > Cookies > _application_name_session.

Illustration book lover

Growing Rails Applications in Practice

Check out our e-book. Learn to structure large Ruby on Rails codebases with the tools you already know and love.

  • Introduce design conventions for controllers and user-facing models
  • Create a system for growth
  • Build applications to last
Read more Show archive.org snapshot

By default Rails >= 5.2 app uses JSON as cookie serializer. Before Marshal was used to serialize cookies. You can find out your application's cookies serializer with Rails.application.config.action_dispatch.cookies_serializer.

# Available modes: json, marshal
def decrypt_session(cookie_string, mode = 'json')
  serializer = case mode
  when 'json' then JSON
  when 'marshal' then ActiveSupport::MessageEncryptor::NullSerializer
  end

  cookie = CGI::unescape(cookie_string.strip)
  salt = Rails.configuration.action_dispatch.encrypted_cookie_salt
  signed_salt = Rails.configuration.action_dispatch.encrypted_signed_cookie_salt
  key_generator = ActiveSupport::KeyGenerator.new(Rails.application.secret_key_base, iterations: 1000)
  secret = key_generator.generate_key(salt)[0, 32]
  sign_secret = key_generator.generate_key(signed_salt)
  encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret, serializer: serializer)
  result = encryptor.decrypt_and_verify(cookie)

  (mode == 'marshal') ? Marshal.load(result) : result
end

Example session cookie:

decrypt_session 'K2lUcDA1MjQ4b05RRU9zU2tNM05ldmIvdGpKVzNDdmRNNVkvbHFVSkNwT1lGODhkN3NZZHRYaDBwQXowR2lheUoxemt1Wm82Z0psYlFNVFM2dmxQaVNvRlhRZGNQQzNXUkswNnNTdVRPR1o5UURrY29CUjJvbEtXb2dwS2dTazZneG5XbjBzMVZISEVyc3ZkQzIxRW9FU3JERHZMWFg3Uk50Z2o0cVZ1eUF2VVR2RjdFbDUvaXlqUEorMEd6NGM0WjBhaTZOQ0NPaGE1NkZCTmVjMzdHajZueU56TVpQZk53bVJKZ21KWW9SdXFuc09WZVlMNS93aERSRlhLTWpEN3Y2M2xtSTlrUjNoS0lNQVMxNUhLNkpDekhhcUViZklLa0pSV3A2NzBtZmc9LS0yS1RmVTJyanl5dHpWQklkSlFQbVJRPT0%3D--50da898541a727755da8cffffbcfbb2c5dd3310b'
=> {
     "session_id"=>"8ef662867ab2457717ba74c143c08733",
     "timestamp"=>1572261371, "warden.user.user.key"=>[[3],
     "$2a$13$FlVrgrbRbFRaFun/4dhaK."],
     "_csrf_token"=>"e03pX09Pqfj3syQp0w9AAJ3fEh7I9Sm8VhndHfqQxgw="
   }

This method is based on Decrypt a Rails 5 session cookie Show archive.org snapshot and extended with the cookies serializer section. You will get an exception like ActiveSupport::MessageEncryptor::InvalidMessage when you use the wrong cookies serializer.

Posted by Emanuel to makandra dev (2019-10-28 10:54)