目次
このページはPHPプロジェクトへの変更提案の日本語訳です。オリジナルは以下のURLを参照してください。
https://wiki.php.net/rfc/session-lock-ini
PHP RFC: session.lock, session.lazy_write 及び session.lazy_destory の導入
- Version: 0.9
- Date: 2013-12-21
- Author: Yasuo Ohgaki, yohgaki@ohgaki.net
- Status: Under Discussion
- First Published at: http://wiki.php.net/rfc/session-lock-ini
概要
提案1:
セッションモジュールはデフォルトでセッションデータをロックします。ロックはセッションを利用するPHPスクリプトを直列化(シリアライズ)することによりセッションデータの完全性を保ちます。(つまり、当時一つのPHPスクリプトのみセッションデータにアクセス可能)
現在のセッションモジュールの動作はセッションデータの完全性を保ちます。しかし、スクリプト実行を直列化しアプリケーションの実行パフォーマンスを低下させます。
Memcache/Memcachedセッションセーフハンドラは、多少の完全性を犠牲にしますがロック制御のINIオプションを既に持っています。
提案2:
セッションデータはデータに変更がなかった場合、必ずしもセッションデータストレージに保存される必要はありません。不必要なセッションデータの書き込みを省略することにより、全体的なシステム性能が向上します。
提案3:
セッションIDが更新された場合にレースコンディションが発生する場合があります。
- スクリプトAがセッションIDを更新
- スクリプトBがサーバーに古いセッションIDでアクセス
現在のセッションモジュールは単純にセッションデータを削除します。このため、スクリプトBは古いセッションIDでサーバーにアクセスします。session.strict_mode=Onでない場合、セッションモジュールはセッションデータを攻撃者が知っているかの知れない古いIDで最初期化します。
レイジーなセッションデータ削除はこの問題を解決します。
提案 1 - session.lock
セッションデータのロックを制御するsession.lockを導入する。
session.lock - デフォルトでOn
session.lock=Onの場合、セーブハンドラーは現在と全く同じ動作をする。
session.lock=Offの場合、セーブハンドラはどうしてもロックが必要な場合にのみセッションデータをロックする。filesセーブハンドラの場合、セッションデータの読み書き時のみロックする。
現在の動作:
Open session data ----------------- ↓ ↑ Read session data | ↓ (Script execution) Locked ↓ Write session data | ↓ ↓ Close session data ------------------
session.lock=Off時の新しい動作:
Open session data ↓ Read session data ← Locked ↓ (Script execution) ↓ Write session data ← Locked ↓ Close session data
提案 2 - session.lazy_wirte
レイジーなセッションデータ書き込みを制御するsession.lazy_writeを導入する。
session.lazy_write - デフォルトはOff
session.lazy_write=Offの場合, セッションモジュールは現在と全く同じ動作をする。
session.lazy_write=Onの場合、セッションジュールはセッションデータが変更された場合にのみセッションデータを保存する。
セッションデータを読み込んだ際、セッションジュールは読み込んだセッションデータのMD5ハッシュを取得する。書き込み時にはセッションデータの古いMD5ハッシュと新しいMD5ハッシュを比較し、MD5ハッシュが異なる場合にのみセッションデータを保存する。
書き込みが省略されるため、セーブハンドラは”最終更新時間”を更新できなくなる。この結果、セッションデータがタイムアウトで削除される。望まないセッションデータの有効期限切れを排除するため、”最終更新時間”を更新する新しいセーブハンドラAPIを導入する。
PS_UPDATE()
session.lazy_write=Onの場合、セッションモジュールはPS_WRITE()の代わりにPS_UPDATE()を呼ぶ。
filesセーブハンドラの実装
filesセーブハンドラの場合、PS_OPEN()でmtimeを更新できるのでPS_UPDATE()は必要ない。filesセーブハンドラのPS_UPDATE()は単純にtrueを返す関数となる。
提案 3 - session.lazy_destroy
レイジーなセッションデータ削除を制御するsession.lazy_destroyを導入する。
session.lazy_destory - デフォルトでOff
セッションモジュールが既に削除済み・アクセス可能を判別する為にはフラッグ/タイムスタンプが必要となる。
オプション1:
タイムスタンプを $_SESSION['SESSION_DESTROYED'] に保存
- 利点 - 単純で高速
- 欠点 - 内部データの露出
オプション2:
Introduce new save handler API that saves flag/time stamp else where. どこかにフラッグ/タイムスタンプを保存するセーブハンドラAPIを導入する。
- 利点 - 内部データ露出なし
- 欠点 - 複雑で遅い
後方互換性の無い変更
なし
提案する PHPバージョン
PHP 5.6 以降
既存のモジュールへの影響
なし
セーブハンドラモジュールの再コンパイルが必要だが、新しいリリースにはいずれにせよ再コンパイルが必要。
php.ini デフォルト
- session.lock=On
- session.lazy_write=Off
- session.lazy_destroy=Off
ハードコードされた設定/development/production.
未解決の課題
- 提案3のオプションの決定
- この提案を既存のfilesセーブハンドラに実装するか、新しいfile_extなどに実装するか
投票オプション
Yes/No
パッチおよびUNITテスト
未作成
実装
リファレンス
なし