Skip to content

Instantly share code, notes, and snippets.

@JoshCheek
Last active June 20, 2018 07:55
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save JoshCheek/7b1c1eb231dfa83098be to your computer and use it in GitHub Desktop.
Save JoshCheek/7b1c1eb231dfa83098be to your computer and use it in GitHub Desktop.
Decrypting a Rails (v4.2.0) session

How to get the values

Salts

$ rails runner 'Rails.application.config.action_dispatch.tap { |c| p encrypted_cookie_salt: c.encrypted_cookie_salt, encrypted_signed_cookie_salt: c.encrypted_signed_cookie_salt }'

Secret Key Base

The session data is encrypted with this value, find it with:

$ rails runner 'p Rails.application.secrets.secret_key_base'

Session Cookie

This is stored in the browser, each browser has its own way of seeing this. We can also just start a server that will print it:

$ echo -e 'HTTP/1.1 200 OK\nContent-Type: text/plain\nContent-Length: 0\n\n' | nc -l 3000 | grep Cookie: | cut -c 9- | tr '; =' \\n

Then visit http://localhost:3000 in your browser to see all the cookies. If there are many cookies, you can identify yours by looking for the key you specified in config/initializers/session_store.rb

$ cat config/initializers/session_store.rb

Examples

Decrypting the session directly

require 'openssl'
require 'json'

session_cookie            = "KzlOUi9lK01vL0Z1Sk1vUUw2QksxM0JpT2xTdm1xMkxoaExMWFZUQWJBUUl0UEgvN1NYUGNtdVVadGZ1REM3YkNCQW56WDhEUDN5WG1KWjdRSjE4d3hoTEJvcHlLSzgwQTdWT1lFMmF3WkpvY0RJV1kveHF1eURSTlgrUkE3N3Q4S2JlY1gwcXdycTArdno3empleS93bC9XODRWMUJCZm1MOUh5dlZVMjJNSjZKc3cwNGFLaXRsVHlCaUpwUW4rN3pZYWlVQ2l3UmVqR2g4aVZLcFl6NUczMkluV0t1cE9CODJKL2RSYVhOZnJsZGhOanEyQ1JGVjNPVlkvQW5MQ3BKTjFjbGNHLzdoaDdPaFRySnFEa1E9PS0teVlEL0lZQ3Y1a1dnZnBnREd1S1lrdz09--ef5736349befb8afcab96954144e9188521326f1"
secret_key_base           = "9b068b0ffb899625a4e11fd75180907439961e3cba7da709d060826de1ab6ae674dde93d2cf62106e5d22a667f9173ace8331f22b1539503ef8d79fc1fe3c5ef"
cipher                    = OpenSSL::Cipher::Cipher.new('aes-256-cbc').tap(&:decrypt)
cipher.key                = OpenSSL::PKCS5.pbkdf2_hmac_sha1(secret_key_base, 'encrypted cookie', 1000, 64) # salt, iterations, key length
unpack64                  = lambda { |str| str.unpack("m").first }
encrypted_data, cipher.iv = session_cookie.split("--").map(&unpack64).first.split("--").map(&unpack64)
JSON.parse cipher.update(encrypted_data) + cipher.final
# => {"session_id"=>"278407bb306a0f61b7490afae89da92f",
#     "_csrf_token"=>"XantipYbR5itu1Gw5mLvo/Q2QVL3pXlLBbI6vnI33I0=",
#     "user_id"=>3,
#     "flash"=>
#      {"discard"=>["notice"], "flashes"=>{"notice"=>"Sign in successful"}}}

Decrypting with ActiveSupport

require 'action_dispatch'

# see readme for how to get these values
session_cookie  = "KzlOUi9lK01vL0Z1Sk1vUUw2QksxM0JpT2xTdm1xMkxoaExMWFZUQWJBUUl0UEgvN1NYUGNtdVVadGZ1REM3YkNCQW56WDhEUDN5WG1KWjdRSjE4d3hoTEJvcHlLSzgwQTdWT1lFMmF3WkpvY0RJV1kveHF1eURSTlgrUkE3N3Q4S2JlY1gwcXdycTArdno3empleS93bC9XODRWMUJCZm1MOUh5dlZVMjJNSjZKc3cwNGFLaXRsVHlCaUpwUW4rN3pZYWlVQ2l3UmVqR2g4aVZLcFl6NUczMkluV0t1cE9CODJKL2RSYVhOZnJsZGhOanEyQ1JGVjNPVlkvQW5MQ3BKTjFjbGNHLzdoaDdPaFRySnFEa1E9PS0teVlEL0lZQ3Y1a1dnZnBnREd1S1lrdz09--ef5736349befb8afcab96954144e9188521326f1"
secret_key_base = "9b068b0ffb899625a4e11fd75180907439961e3cba7da709d060826de1ab6ae674dde93d2cf62106e5d22a667f9173ace8331f22b1539503ef8d79fc1fe3c5ef"

ActionDispatch::Cookies::EncryptedCookieJar.new(
  { '_dinner_dash_session' => session_cookie },
  ActiveSupport::KeyGenerator.new(secret_key_base, iterations: 1000),
  { encrypted_cookie_salt: 'encrypted cookie', encrypted_signed_cookie_salt: 'signed encrypted cookie', serializer: :json },
)['_dinner_dash_session']
# => {"session_id"=>"278407bb306a0f61b7490afae89da92f",
#     "_csrf_token"=>"XantipYbR5itu1Gw5mLvo/Q2QVL3pXlLBbI6vnI33I0=",
#     "user_id"=>3,
#     "flash"=>
#      {"discard"=>["notice"], "flashes"=>{"notice"=>"Sign in successful"}}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment