symfonyでsession_regenerate_id()
session_regenerate_id()を使うとセッションIDを簡単に変更できるので、少なからずセッションハイジャック対策ができる。
symfonyで認証画面を作り、ログイン時にsession_regenerate_idしてIDを再発行しようと思ったけど、デフォルトのsfSessionStorageを使うとID変更前に処理が終わってしまい画面遷移したあとに変更後のIDでセッションが利用できない。
なので、とりあえず自前でmySessionStorageクラスを用意して回避することにした。
project/lib/storage/mySessionStorage.class.php
<?php class mySessionStorage extends sfMySQLSessionStorage // ※ウチの環境ではsfMySQLSessionStorage使ってるので { public function initialize($context, $parameters = null) { parent::initialize($context, $parameters); } public function regenerateID () { $old_session_id = session_id(); session_regenerate_id(); $new_session_id = session_id(); //destroy the old session ID session_id($old_session_id); session_destroy(); //need to re-register all user-level handlers again (should they exist) @session_set_save_handler(array($this, 'sessionOpen'), array($this, 'sessionClose'), array($this, 'sessionRead'), array($this, 'sessionWrite'), array($this, 'sessionDestroy'), array($this, 'sessionGC')); //starts the new session ID again session_id($new_session_id); session_start(); } }
app/config/factories.yml
all: storage: class: mySessionStorage param: db_table: session db_id_col: id db_data_col: data db_time_col: updated_at database: propel session_cookie_domain: .example.com // 実際はプロジェクトのドメイン名
あとは任意のコントローラ側でmySessionStorageのregenerateIDを呼ぶ。
<?php pubic function executeLogin() { // 省略 $this->getContext()->getStorage()->regenerateID(); // 以下ログイン処理 }
これで一応上手くいく。ていうか公式で対応してほしいんだが。