$_SESSION は、定義済み変数のひとつであり、ページ遷移後やリロード後も値を保持し続けることができる変数です。
ECサイトのように、複数ページで値を保持しておきたい場合などに使用します。
なお、$_SESSIONは、スーパーグローバル変数であり、プログラム全体のどのスコープでも呼び出せます。
関数の内部で呼び出す場合、グローバル変数はグローバル宣言しますが、スーパーグローバル変数は、グローバル宣言すら必要ありません。
<?php session_start(); // セッションを開始 $_SESSION[キーA] = '値'; // セッション変数をセット $_SESSION[キーB] = array( '値A', '値B', '値C' ); // 配列をセットすることも可能 ?>
<?php session_start(); // セッションを再開 $_SESSION[キーA]; // セッション変数を呼び出す $_SESSION[キーB][0]; // セッション変数にセットした配列の1つ目の値を呼び出す $_SESSION[キーB][1]; // セッション変数にセットした配列の2つ目の値を呼び出す $_SESSION[キーB][2]; // セッション変数にセットした配列の3つ目の値を呼び出す ?>
PHPのセッション管理は、セッションの固定化(Session Fixation)問題というものがあります。
この問題に対応するために、ログイン後にセッションIDを作り直して、ログイン後のセッションを保護するという対策が必要です。
なお、このセッションの固定化を原因としたセッションハイジャックを防ぐために、セッションIDを置き換える関数「session_regenerate_id」がPHPには用意されています。
session_regenerate_id() を使うとセッションIDは新しいものと置き換わりますが、セッション情報は維持されるという特徴があります。
ログイン後にのみ重要なデータを参照て処理する場合、ログイン後に session_regenerate_id() でセッションIDを作り直せばログイン後のセッションは保護されるのでセキュリティ上の問題はほぼ発生しません。
しかし、使い方や挙動などで注意すべき点がいくつかあるため注意が必要です。
ログインが必要なサイトのURLが次のURLだとします。
http://example.com/login/
攻撃者はURLにセッションIDを記述したURLリンクを作成します。
http://example.com/login/?PHPSESSID=abcdefg
攻撃対象者がこのリンクをクリックするとセッションIDがabcdefgに設定されているので攻撃者はこのセッションIDを利用してサイトにアクセスできるようになってしまいます。
PHP 5.1 からは第1引数が追加されました。引数にtrueをセットすることで、古いセッションIDは破棄されて毎回新しいIDが振られます。
session_start(); session_regenerate_id(TRUE);
PHP 5.1.0 までは、古いセッション情報が削除されずにそのまま残ってしまいます。
そのため、PHP5.1.0 までの場合は、古いセッション情報を明示的に削除する必要があります。
session_start(); $old_id = session_id(); session_regenerate_id(); unlink(session_save_path() . 'sess_' . $old_id);
session_regenerate_id() を使うと、毎回セッションIDが変わるため通信エラーが起こった際にセッションが切れてしまう可能性があります。
対策としては、SSLを利用してログイン時のみ書き換える仕様にするのがいいのかもしれません。
携帯電話からPHPのセッションを機能を使う場合、端末によってはクッキーが利用できない場合があるため、そのままでは使うことができません。
下記の設定が有効になると、リンクの後ろに自動でセッションIDが付加され、セッション変数が引き継げるようになります。
※ただしクッキーが使える端末で、「session.use_cookies On」の場合には、セッションの管理にはクッキーが優先して利用され、URLにセッションIDはつきません。
セッションIDが付加された例: <a href="index.php?PHPSESSID=b37b5e8e31118c45e19a5fb6b70c215a">トップへ</a>
なお、ページの移動に静的HTMLを挟んだり、引数をつけないでリダイレクトしたりすると、セッションは切れてしまいますので注意が必要です。
セッションを使いたい場合は、インストール時のconfigureオプションに、「-enable-trans-sid」を付ける必要があります。
なお、Windowsの場合は特に設定の必要はありません。
また、「php.ini」の設定で、次のように設定します。※設定変更後はWebサーバの再起動が必要です。
session.use_trans_sid = 1
なお、設定内容は、phpinfoで確認できます。
「.htaccess」でも設定することができます。※.htaccessでの設定上書きが許可されている場合のみ
php_flag session.use_trans_sid On
なお、設定内容は、phpinfoで確認できます。
PHPのコード内で、下記のコードでの設定できますが、その場合は「session_start();」より前に実行する必要があります。
ini_set('session.use_trans_sid', '1');
上記設定のままですと、URLに固定のセッションキーがついたままの状態のため、リンク先のページにRefererが漏れてしまったり、メール等でURLを転送した場合などにセッションハイジャックされてしまう可能性があります。
そこで安全度を高めるために、次のような対応策を平行して行うと良いようです。
auとソフトバンクの最近の機種ではクッキーが利用できます。
クッキーが利用できれば、URLにセッションIDを付加しなくてすみますので、URLからの漏洩を防ぐことができます。
セッションの管理にクッキーを優先して利用するには、「php.ini」または「.htaccess」で、「session.use_cookies On」と設定されている必要があります。
まず.htaccessなどで、携帯キャリアのIPアドレスからのみアクセス可能な状態にします。
その状態でセッションに端末IDを格納し、アクセスの度に認証チェックを行うことでなりすましを防ぎます。
IPアドレスの制限をかけるのは、Refererが漏れている場合は、端末IDも同時に漏れているケースが多いためです。
端末IDはリクエストを偽造することで、なりすまされる可能性があるため、携帯実機からのアクセスのみとすることで安全度を高めます。
「session_regenerate_id」は、アクセスの度にセッションIDを変更するためのものです。
PHPのバージョンによって対処法が異なりますので注意が必要です。
詳しくは下記を参照して下さい。
session_start(); session_regenerate_id(TRUE);
// セッション開始 session_start(); // 古いセッションを保存 $sess_tmp = $_SESSION; // セッション変数を破棄 session_destroy(); // セッションIDを再生成 session_start(); session_regenerate_id(); // セッションを元に戻す $_SESSION = $sess_tmp;