Railsが提供するセッション機能について

f:id:ryoutaku_jo:20190301095437p:plain

【結論】
・セッションとは、
 ステートフルな通信を実現する為に用いられる技術

・ステートフルとは、前に通信した情報を
 引き継いで通信を行う方法

・逆に、前に通信した情報を保持しない通信方法は、
 ステートレスと呼ばれる


【目次】


【本題】

ハッキング出来なかったが勉強になった

前回の記事で、同期の作ったアプリをハッキングした時の話を書きました。
ryoutaku-jo.hatenablog.com

最終的にセッションに保持された値を改竄する手段が思いつかず、
ハッキングを諦めました(いずれ再挑戦する!)が、
その過程でセッション(Cookie)について色々調べて勉強になったので、今回はそれをまとめます。

セッションとは

ステートフルな通信を実現する為に用いられる技術です。

ステートフルとは、前に通信した情報を引き継げる通信方法です。
逆に、前に通信した情報を保持しない通信方法を、ステートレスと呼びます。

下記の様な日常会話に当てはめるとイメージしやすいかもしれません。

・ステートレスな場合

男「初めまして、都手藻影臼男です」
女「初めまして」
↓(1週間後)
男「お久しぶりです」
女「・・・あなた誰ですか?」

・ステートフルな場合

男「初めまして、池面太郎です!」
女「こちらこそ初めまして!!」
女(脳裏に焼き付けておこう!!)
↓(1週間後)
男「お久しぶr」
女「お久しぶりです 、池面太郎さん!! 」

HTTP通信はステートレスなので、「クライアントがリクエストを送信し、それに対してサーバがレスポンスを返す」
という一連の通信がそれぞれ独立しているので、前に通信した内容を引き継ぐ事が出来ません。

この特性から、セキュリティ面で優れているのですが、ある機能の実装を困難にしてしまいます。
それがログイン機能(アカウント認証機能)です。

なぜなら、一度ログインしたとしても、通信がステートレスだと、
次の通信ではログインしたという内容が無かったことになってしまうので、
またログインし直さないといけなくなってしまいます。

そこで登場するのが、セッションです。

セッションを用いれば、通信が切り替わっても
ログイン情報を保持しておけるので、ログインし直す必要なく、
次に操作を行う事が可能となります。

セッションの実装方法

セッションは下記の様にして実装できます。

session[キー] = 値

railsdoc.com

セッションの暗号化

Railsが初期設定の状態であれば、
セッションの情報は、ブラウザのCookieに保存されます。

ブラウザ上にあるので、悪用されるリスクを懸念すると思いますが、
上記の実装方法だと、自動的に暗号化してくれます。

CookieStoreはセッションデータの保管場所をencrypted cookie jarで安全に暗号化します。
これにより、cookieベースのセッションの内容の一貫性と機密性を同時に保ちます。
暗号化鍵は、signed cookieに用いられる検証鍵と同様に、secret_key_base設定値から導出されます。

Rails 5.2から暗号化cookieとセッションはAES GCM暗号化を用いて保護されるようになりました。
この暗号化手法は、認証と暗号化を一括で行える認証付き暗号(Authenticated Encryption)の一種であり、
生成される暗号化テキストが従来のアルゴリズムに比べて短いという特徴があります。AES GCM方式で暗号化されたcookieの鍵の導出には、config.action_dispatch.authenticated_encrypted_cookie_salt設定値で定義されるsalt値が用いられます。

railsguides.jp

とはいえ、Cookieが丸ごと盗み出されてしまうと、
それをそのまま利用した再生攻撃に利用されるケースもあるので、
暗号化も万能ではありません。

Rails セキュリティガイド - Rails ガイド

セッションの管理方法

Railsのセッション管理方法には、
先ほどの方式と合わせて、3つの管理方法があります。

・CookieStore
先ほど説明した方式で、
クライアントのブラウザのCookieに、セッション情報を保存する方法です。
デフォルトでは、こちらが設定されています。

メリット・・・デフォルトなので直ぐ使える。処理が早い。
デメリット・・・クライアント側に保存されるので、不正利用しやすい

・ActiveRecordSessionStore
「ActiveRecordSessionStore」というgemを用いた方法です。
DBへセッション情報を保存できます。

メリット・・・サーバー側に保存するので、不正利用されにくい
デメリット・・・DBに負荷が掛かりやすい

・DalliStore
「Dalli」というgemを利用した方法です。
サーバーのメモリにセッション情報を保存します。

メリット・・・サーバー側に保存するので、不正利用されにくい。処理が早い
デメリット・・・一番導入が面倒

《今日の学習進捗》

就活とセッションの勉強。

学習開始からの期間 :83日
今日までの合計時間:830h
一日あたりの平均学習時間:10h
今日までに到達すべき目標時間:758h
目標との解離:72h
「10,000時間」まで、

残り・・・「9170時間!」