ユーザ用ツール

サイト用ツール


php-rfc:session-lock-ini

このページはPHPプロジェクトへの変更提案の日本語訳です。オリジナルは以下のURLを参照してください。

https://wiki.php.net/rfc/session-lock-ini

PHP RFC: session.lock, session.lazy_write 及び session.lazy_destory の導入

概要

提案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テスト

未作成

実装

リファレンス

なし

Rejected Features

php-rfc/session-lock-ini.txt · 最終更新: 2013/12/23 05:41 by Yasuo Ohgaki