Comments
Description
Transcript
2011/6/2 セッションとは
セッションとは Web ページ間で変数を保持する方法として、フォームの hidden フィールドや Cookie、 セッション変数などが使用可能ですが、重要なデータの受け渡しを行う場合、セッショ ン変数を使用します。 セッション変数は、ユーザから送信された重要情報をサーバ側で保存し、代わりに、 Cookie や、GET 変数、POST 変数にセッション ID と呼ばれる、一般的に推測しにく い文字列をクライアントに持たせることでセッションを維持します。これにより、重要 なデータを他のユーザに参照されたり、改ざんされたりする可能性を低くすることがで きます。 セッションを使用する際のセキュリティ問題としては、セッション ID を他のユーザに 盗まれるセッションハイジャックという問題があります。セッション ID は、ブラウザ のバグや、クロスサイトスクリプティングによって他のユーザに盗まれる可能性があり ます。Web アプリケーションでセッション ID を使用する場合は、簡単にセッション ID を盗まれないようにできる限りの対策を行う必要があります。 セッションの仕組み セッション機能を使うには、 「$_SESSION」というスーパーグローバル変数に値を格納 します。 PHP はセッション変数 ($_SESSION)の値を Web サーバー上のファイルに保管します。 また、PHP の session_start 関数は、ブラウザから送られてくるクッキーの値をもとに、 どのブラウザかを特定し、そのブラウザ専用のセッション変数を復元させます。 セッションの開始 PHP でセッション変数を使用する場合、session_start() 関数を呼び出す必要があります。 もし、php.ini で session.auto_start を "1" に設定した場合、自動的にセッションが開 始されますので session_start() を呼び出す必要はありません。 セッションの開始時には、以下の処理が行われます。 •まだセッション変数が保存されていない場合、セッション変数の保存データの領域を確 保 •クライアントからセッション ID が送信されていた場合、セッションの保存領域から $_SESSION にセッション変数を復元 •指定された確率でガーベージ・コレクション(後で説明)を起動 スクリプトの終了時(出力時)には以下の処理が行われます。 •確保した保存データ領域にセッション変数のデータ書き込み •クライアントにセッション ID が含まれた Cookie を送信(HTTP レスポンスヘッダ) •session.use_trans_sid が "1" に設定されている場合、ユーザが Cookie を無効にして いた場合でもセッションが継続するように、url_rewriter.tags の設定に従って HTML の URI 指定やフォームの hidden フィールドにセッション ID を埋め込む処理を行う セッション変数を保存する領域は、以下の設定によって決定されます。デフォルトでは、 /tmp に sess_dbfca507eb62b716bc2b8296159ccb15 (sess_ と セッション ID)のよう なファイルが作成されます。 •session.save_handler (デフォルト: "files") •session.save_path (デフォルト: "/tmp") セッション ID は Cookie -> GET -> POST の順で session.name(デフォルトでは "PHPSESSID") で 指 定 さ れ た キ ー を 検 索 し ま す 。 例 え ば 、 Cookie($_COOKIE['PHPSESSID']) と GET 変数($_GET['PHPSESSID'])に別のセッ ション ID が指定されていた場合、Cookie のセッション ID が優先されます。 また、PHP 4.3.0 から導入された session.use_only_cookies を "1" に設定すると、セッ ション ID として Cookie のみを確認するようになります。これは、PHP マニュアルで は、セッション ID を URL に埋め込む攻撃を防ぐためとされています(セッション処理 関数(session) session.use_only_cookies)。セッションを Cookie のみで管理するのであ れば、session.use_only_cookies は On に設定しておくと、Session Fixation 攻撃を防 止できる可能性が高くなります(クロスサイト・スクリプティングが可能な場合は Cookie の内容を改ざんされる可能性がありますので、絶対に安全というわけではありません)。 この設定を行うと、session.use_trans_sid の機能は無意味になりますので、その場合は session.use_trans_sid を無効にしておくと良いと思います。 セッションの終了 明確にセッションが終了したと判定することは難しいですが、ユーザがセッションの終 了を宣言(例えば、ログアウトするなど)した場合は、session_destroy() 関数を呼び出す ことで、サーバに保存されたセッション情報が破棄されます。 PHP マニュアル : session_destroy() によると、セッションに関するグローバル変数や、 セッション Cookie は破棄しないとされています。実際に、session_destroy() が呼び出 された後も、同じセッション ID が継続して使用されます。 完全にセッションを破棄する場合は、PHP マニュアルの例に従って処理を行います。 例 1. $_SESSION でセッションを破棄する <?php // セッションの初期化 // session_name("something")を使用している場合は特にこれを忘れないように! session_start(); // セッション変数を全て解除する $_SESSION = array(); // セッションを切断するにはセッションクッキーも削除する。 // Note: セッション情報だけでなくセッションを破壊する。 if (isset($_COOKIE[session_name()])) { setcookie(session_name(), '', time()-42000, '/'); } // 最終的に、セッションを破壊する session_destroy(); ?> PHP マニュアル: session_destroy session_id() の返り値は外部からの入力により改ざん可能ですので、session_id() の値が 期待通りかどうかを確認してから使用してください。上記のコードのように、不正な値 の場合は、エラーとして処理を終了させた方が安全です。 セッション ID の変更 http 通信では、Cookie も暗号化されずにネットワークを流れるため、同じセッション ID を長時間使い続けると、他人に知られてしまったり、盗聴されたりする危険性が高く なります。定期的にセッション ID を変更ことでその危険性を低くすることができます。 PHP 4.3.2 以降であれば、session_regenerate_id() を使用することでセッション ID を 変更することができます。使い方は、以下のように session_start() の後に呼び出すだけ です。 session_start(); session_regenerate_id(); また、session_regenerate_id() は、一つ前に使用していたセッション情報を削除しない ことに注意してください。session_regenerate_id() は、新しく別の領域にセッション情 報を保存しますが、前のデータを削除しないため、古いセッション情報は残ったままに なり ます。古 いセッション 情報は、 使用可能な状 態になっ ていますので 、単純 に session_regenerate_id() を呼び出せば良いというものではありません。必要に応じて以 下のような対策を行ってください。 古 い セ ッ シ ョ ン 情 報 を 削 除 す る 方 法 と し て 、 PHP 5.1.0 以 降 の 場 合 は 、 session_regenerate_id() の第 1 引数にオプションが設定されています。これを TRUE にすると、セッション情報を削除するようになっています。PHP 5.1.0 を使用している 場合は、session_regenerate_id( TRUE ) を実行するだけで自動的に古いセッション ID は削除されます。