セッション管理の不備に対する根本的対策は、以下の記事を参照してください。
これを PHP で実現すると以下のようになります。
■1.推測困難なセッション ID を利用する
PHP はデフォルトで推測困難なセッション ID を生成しません。推測困難なセッション ID を生成するためには、Linux では php.ini の設定を以下のようにする必要があります。
session.entropy_file = /dev/urandom session.entropy_length = 32
Windows 環境では、session.entropy_file を指定する必要はなく、session.entropy_length は0以外を指定します。
なお、この設定をしても、セッション ID の長さが変わるわけではありません。
■2.セッション ID を URL に含めない
PHP でセッション ID を URL に含めないためには、php.ini を以下のように設定する必要があります。
session.use_cookies = 1 session.use_only_cookies = 1
■3.HTTPS 通信で利用する Cookie には secure 属性を付与する
PHP で Cookie に secure 属性を付与するにはsetcookie関数を以下のように記述します。HttpOnly 属性も付与したほうがよいでしょう。
setCookie("sample", "value", 0, "/", null, TRUE, TRUE);
このレスポンスヘッダーのは以下のようになります。
Set-Cookie: sample=value; path=/; secure; httponly
セッション ID に secure 属性と HttpOnly 属性を付与する方法は以下の記事を参照してください。
■4-1.ログイン後にセッションを新規に開始する
■4-2.ログイン後にセッション ID とは別の秘密情報を持ち、各ページでその値をチェックする
PHP では 4-1 の方法を採用します。
session_regenerate_id(true) を実行することで、既存のセッション情報を破棄し、新しいセッション情報、セッション ID を生成します。
・login.php
<html> <body> <h1>ログイン</h1> <form action="logincheck.php" method="post"> ID:<input type="text" name="id"><br> Password:<input type="password" name="password"><br> <input type="submit" value="ログイン"> <input type="reset" value="リセット"> </form> </body> </html>
・logincheck.php
<?php session_start(); //パラメーター取得 $id = $_POST['id']; $password = $_POST['password']; //簡易ログイン if ($id == "yamada" && $password == "pass") { //ログイン成功 //セッション ID の振り直し session_regenerate_id(true); //セッションに値を格納 $_SESSION['id'] = $id; //リダイレクト header("HTTP/1.1 301 Moved Permanently"); header("Location: welcome.php"); } else { //ログイン失敗 //リダイレクト header("HTTP/1.1 301 Moved Permanently"); header("Location: login.php"); } ?>
・welcome.php
<?php session_start(); ?> <html> <body> <h1>ようこそ、<?php echo htmlspecialchars($_SESSION['id'], ENT_QUOTES, "UTF-8") ?>さん</h1> </body> </html>
参考
Webアプリケーションセキュリティに関する記事は、以下のページにまとまっています。ぜひご確認ください。
コメント