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 online protection

Rails Long Term Support

Rails LTS provides security patches for old versions of Ruby on Rails (2.3, 3.2, 4.2 and 5.2)

  • Prevents you from data breaches and liability risks
  • Upgrade at your own pace
  • Works with modern Rubies
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)