Rails 4: See Cookie


I wondered how the Rails cookie structure is and checked it.

Environment

  • Rails 4.2.5
  • Ruby 2.0.0p481

Code to Decode Cookie Value

First, I checked the cookie value. Launch rails console, bundle exec rails c, and execute the following code.

Set cookie value to the variable cookie, and set secret_key_base value to the variable key.

cookie value

If you use Chrome browser (Version 47.0.2526.106), you can see the cookie value with developer tools. Open Developer Tools and choose resource view and select cookie that you want to see on left side tree.

Cookie is name and value pair. The name of the cookie generated by Rails 4 is like _xxx_session as default. You can specify it as Rails.application.config.session_store, which is written in config/initializers/session_store.rb usually.

secret_key_base value

Normally, it is written in config/secrets.yml.

salt and secret

In the above code, I set values defined as config to salt and secret. It is “encrypted cookie” and “signed encrypted cookie” as default.

You can see that values by checking cookies variable in controller.

Example of Cookie Value

Rails のテスト用アプリケーションでクッキーの値を取得してみました。 テスト用アプリケーションでは devise gem を使用しており、 クッキーを取得したとき ユーザID 2 のユーザでログインしていました。

デコードの処理内容

クッキーデコード時の処理内容を確認します。

  1. CGI.unescape でクッキーに入っている値を URLデコード します。

  2. キージェネレータを作成します。 キージェネレータはシークレットキーの値とイテレーション回数をインスタンス変数にもつオブジェクトで、初期化処理は次のようになっています。

    デコード時にiterationsに 1000 を代入しているのは、Rails::Application class で次のように1000 が使用されているからです。

  3. Generate key from salt. generate_key method is defined as below.

    OpenSSL::PKCS5.pbkdf2_hmac_sha1 generates key for encryption by hash method sha1. In this case, iterates 1000 times.

  4. Generate sign_secret like above.

  5. Crete MessageEncryptor object. Initializer of MessageEncryptor is defined as below.

    options[:chiper]は設定されないまま実行されますから、 AES-256-CBC が暗号化方式として設定されます。 AES は共通鍵暗号で、 ここで作成したMessageEncryptorオブジェクトはencryptdecryptが可能です。

  6. verify and decrypt. verify を行うのは padding attack を防ぐためだそうです。 It doesn’t decrypt simply, so incorrect secret value trigger exception and you can’t get decrypted value.

Generate Cookie Value

前節で書いたのと同じ要領で MessageEncryptor のオブジェクトを作成して encrypt_and_sign を実行すれば cookie の値を作成できます。 encrypt_and_signメソッドは実行する度に結果が変わります。