はじめに
「ログイン認証に成功したらセッションIDを更新する」というのは、セッション固定化攻撃(Session Fixation)の対策としては有名な話かと思う。
PHPのsession_regenerate_idのようなWebアプリケーション・フレームワークにセッションIDを再生成する関数が用意されていればいいのだけど、そういう関数がない場合は、どういう実装方法があるのかという点について考察した。
フレームワーク提供のHTTPセッションID + 独自乱数 = HTTPセッションID
単純な話で、ログイン時にセキュアな乱数※を生成して、それをセッション関数/セッションオブジェクトとクッキーに同時に保存する。
セッションIDの一意性はWebアプリケーション・フレームワーク提供のセッションIDが保証しているので、自作側(上記のセキュアな乱数)には一意性の必要性はなく、推測困難性だけでよい。
なので、適当にセキュアな乱数を生成すればいい。
(セキュアな乱数が、以前の作成値とたまたま偶然にも同じ値になるかも...とかいうのは考慮しなくてよい。ということ)
以降は、このクッキーの値とセッション変数/セッションオブジェクトの値が、ヌルでなくかつ同一かどうかをチェック。
同一でない場合は、強制ログアウト処理(ログイン画面へリダイレクト)。
そして自作クッキーとセッション変数を破棄する。
※ (普通の乱数+内部状態{内部でしか使っていないユーザIDとか})をSHA2する、でもよいと思う。
※ 念のためにセキュアな乱数を、さらにSHA2で追い込んでも、よいと思う。
(セキュアな乱数がセキュアでなかった時にもSHA2しているし、SHA2の脆弱性が仮に見つかったとしても、シードがセキュアな乱数なので、ひとまず安心できると思う)
(使用しているセキュア乱数を呼ぶ関数とSHA2の脆弱性が、同時に見つかるとヤバいけど...)
余談
フレームワークによっては、
・一意性のある値(連続する番号)
・推測困難な値
という2つの別々のクッキーを吐き出して、この2つのクッキーをまとめて「セッションID」とするフレームワークもあるよ。
なので、2つ以上のクッキーでセッションIDを構成しても特に問題にはならないと思う。
その他
他のやり方もあると思う。
そういうのはコメントに書いてほしい。