sessionのよく誤解してしまいそうな点

PHPの標準機能の中で1,2を争うくらい*1よく使うセッション機能。

ただ、どのような思惑かはさておき現在実装されているものに関して注意しておかなければいけない点がいくつかあるのでまとめ。

セッションについてのマニュアルはPHP: セッション関数 - Manual

  1. セッションの固定化(Session Fixation)
  2. session.save_pathの設定によってはガーベッジコレクションが行われないことがある。
  3. session.gc_probabilityとsession.gc_divisorの値によってはsession.gc_maxlifetimeで指定した以上にセッションが残る可能性がある

1について
詳しくは2006年2月 – yohgaki's blog
マニュアルからリンクされているSession Fixation Vulnerability in Web-based Applicationsを見てもらうとして
ユーザから渡ってきたセッションIDを信じすぎてしまっている所に問題があり。


2について

session.save_path は、保存ハンドラに渡される 引数を定義します。デフォルトのファイルハンドラを選択した場合、 ファイルが作成される場所のパスになります。デフォルトは、 /tmp です。 session.save_pathのパスの深さが2より大きい場 合、ガーベッジコレクションは行われません。 session_save_path()も参照してください。

オプションの引数としてN(数値)を指定できます。 これはセッションファイルを分散して保存する際に ディレクトリ階層レベルを決定します。 例えば、'5;/tmp'とすると /tmp/4/b/1/e/3/sess_4b1e384ad74619bd212e236e52a5a174If という位置にセッションファイルを生成します。


(中略)

0以上のNが指定されている場合には自動ガーベッジコレクションが機能しないことに注意してください。

どちらの指定の仕方でもセッション保存パスが深さ1の場合(/xxxxxx)しかガーベッジコレクションが働かない。
時間があるときに実際に実験してみる必要があるけれどマニュアルに記載されているのでほぼ間違いないかと。


と、書いているうちに実験してくれた人がいてどうも階層に関係なくガーベッジコレクションが働く模様。
おかしいなと思い、英語のマニュアルも確認してみると
PHP: Session Functions - Manual

session.save_path defines the argument which is passed to the save handler. If you choose the default files handler, this is the path where the files are created. Defaults to /tmp. See also session_save_path().

どこにもそんなこと書いてなかった、、(ノ∀`)タハー
制限がなくなったけど日本語ドキュメントはその修正が反映されてないのかなぁ。


ちなみに2つめの記述方法の場合は

Also note that if N is used and greater than 0 then automatic garbage collection will not be performed, see a copy of php.ini for further information.

まだ、制限として残っているっぽい。



3について
アクセスされる毎に\frac{session.gc_probability}{session.gc_divisor}の値の確立でガーベッジコレクションが行われ、
行われた時に初めてsession.gc_maxlifetimeを超えているものが消されるので
値によってはそもそもガーベッジコレクションがなかなか行われずに
セッション情報が消えない場合がある。

*1:他は何よ?といわれても答えられない;;´ー`