CakePHPでセッションを使ったことはあったけど,内部のPHPがどういう挙動を取っていたのかを知らなかったので,その辺りについて触れつつ,セッションを使う際のセキュリティに関することをまとめる。
セッションとは
- Webサーバーとブラウザ間で継続した通信を行うために必要な機能
- セッション機能は,クッキー機能を利用している
PHPでセッションを行う際の具体的な挙動
session_start関数を使用すると,セッションが開始され,$_SESSION
変数が使用できるようになる。
セッション中は$_SESSION
変数の内容がサーバ上に保存され,ユーザを一意に識別する為の識別子としてセッションIDが付与される。セッションIDごとにサーバ上に保存された情報が振り分けられるので情報が混合してしまうようなことはない。ちなみにセッションIDには”3f17b855b4bf21022d150f407eb4415d”のようなランダムな値がデフォルトで割り当てられるので重複は確率的にない。セッションIDはユーザが使用するブラウザに保存されるが,このブラウザ内に保存する技術をCookieと言う。Cookieには有効期限という概念があり,PHP側でCookieの有効期限をある程度自由に設定することができる。その為,SNSなどのウェブサービスで実装されている「持続ログイン」はこのCookieを用いて実現されている。
セキュアにセッションを行うには
セッションに関して考慮しなければいけないセキュリティ上の懸念点として,以下の2点がある。
- セッションハイジャック
- クロスサイトリクエストフォージュリ(CSRF)
以下より,これらについて説明する。
セッションハイジャックについて
セッションハイジャックは,セッションIDが何らかの方法(セッションフィクセイションなど)で盗まれたり,生成されるセッションIDが推測可能であったりすると,この攻撃の対象となってしまう。セッションハイジャックの対象になってしまうと,例えば,SNSなら攻撃者が対象者に成りすましてログイン後の操作をすることが可能になってしまう。
セッションハイジャックで主に使われる攻撃手法は,セッションフィクセイションと呼ばれる方法で,攻撃者が対象者のセッションIDを書き換えてしまう手法である。
例えば,http://example.com/
というセッション機能が使用されているウェブサイトがあった場合に,対象者がセッション中に,攻撃者が用意したhttp://example.com/?PHPSESSIONID=AAA
にアクセスすると強制的にセッションIDがAAA
に書き換えられてしまう。後に,攻撃者がhttp://example.com/?PHPSESSIONID=AAA
にアクセスすることでセッションハイジャックが成功してしまう。
対策
セッションハイジャックを防ぐ方法としては,セッションIDを再発行する方法が挙げられる。PHPではsession_regenerate_id()
を使うことでセッションIDを再発行することができる。ユーザーがウェブサイトにアクセスする度にセッションIDの再発行を行うことで,ユーザがもし,攻撃用のhttp://example.com/?PHPSESSIONID=AAA
を踏んでしまった場合でもhttp://example.com/?PHPSESSIONID=AAA
にアクセスした時点でAAA
とは別の新たなセッションIDが発行される。
クロスサイトリクエストフォージュリ(CSRF)について
クロスサイトリクエストフォージュリ(以下,CSRFと略称)は,対象者がウェブサイトでのセッション中に,攻撃者が用意した攻撃用のウェブサイトに対象者を誘導し,攻撃用のウェブサイトにて対象者がセッション中のウェブサイト上で重要操作を行わせる為のURL(スクリプト)を踏ませる攻撃手法である。
CSRFは攻撃者にとって簡単に実行できる部類の攻撃方法で,近年だとはまちちゃん事件が有名である。はまちちゃん事件は,有名SNS「mixi」上でCSRF攻撃が実際に行われた事件で,mixiにログイン中のユーザを攻撃者が攻撃用のウェブサイトに誘導し,攻撃用のウェブサイトにて,mixiに日記を書き残す操作をするURLを踏ませるというものであった。攻撃によって作成された日記の記事には攻撃用のウェブサイトへのリンクが張ってあり,アクセスを促す内容の文章も記載されていたので,被害は大きく拡散した。
対策
CSRFへの対策として以下の2つが挙げられる。
- 照合情報を使って認証する
- HTTPリファラを確認する
照合情報を使って認証する
セッションIDやページトークンなどをフォームのhiddenフィールドに埋め込み,その照合情報がフォームデータに含まれていない場合は処理を見合わせるようにする。このようにすることで,正常なリクエストと不正なリクエストを見分けることができ,CSRFを防ぐことが出来る。
HTTPリファラを確認する
PHPでは$_SERVER["HTTP_REFERER"]
にリファラの情報が入ってるので,外部サイトからの訪問であり,且つ,ウェブサイト上で重要な操作をする行動を条件式で判別する。このようにすることで,正常なリクエストと不正なリクエストを見分けることができ,CSRFを防ぐことが出来る。
参考
第8回 セッションの仕組みを知ろう (その1)
10日で覚えるPHPのキソ 第 10 回 セッション(SESSION)
とくまるひろしのSession Fixation攻撃入門
IPA ISEC セキュア・プログラミング講座:Webアプリケーション編 第4章 セッション対策:リクエスト強要(CSRF)対策
Wikipedia セッションハイジャック
Wikipedia クロスサイトリクエストフォージェリ