PHPで責任あるセッションセキュリティを維持するためのガイドラインは何ですか?ウェブ全体に情報があり、それがすべて1か所に到着する時が来ました!
13 に答える
セッションを安全に保つために、いくつかのことを行う必要があります。
- ユーザーを認証したり、機密性の高い操作を実行したりする場合は、SSL を使用します。
- セキュリティ レベルが変更されるたびに (ログインなど)、セッション ID を再生成します。必要に応じて、リクエストごとにセッション ID を再生成することもできます。
- セッションをタイムアウトにする
- レジスタ グローバルを使用しない
- 認証の詳細をサーバーに保存します。つまり、Cookie でユーザー名などの詳細を送信しないでください。
- を確認してください
$_SERVER['HTTP_USER_AGENT']
。これにより、セッション ハイジャックに対する小さな障壁が追加されます。IPアドレスも確認できます。ただし、これにより、複数のインターネット接続での負荷分散などのために IP アドレスを変更しているユーザーに問題が発生します (これは、ここの環境の場合です)。 - ファイル システム上のセッションへのアクセスをロックダウンするか、カスタム セッション処理を使用します。
- 機密性の高い操作については、ログインしているユーザーに認証の詳細を再度提供するよう求めることを検討してください
ガイドラインの 1 つは、セッションのセキュリティ レベルが変わるたびにsession_regenerate_idを呼び出すことです。これにより、セッションのハイジャックを防ぐことができます。
私の2セント(またはそれ以上):
- 誰も信じない
- フィルター入力、エスケープ出力(Cookie、セッションデータも入力です)
- XSSを避けてください(HTMLを整形式に保ち、PHPTALまたはHTMLPurifierを見てください)
- 多層防御
- データを公開しないでください
このトピックに関する小さいながらも優れた本があります:ChrisShiflettによるEssentialPHPSecurity。
EssentialPHPセキュリティhttp://shiflett.org/images/essential-php-security-small.png
この本のホームページには、いくつかの興味深いコード例とサンプルの章があります。
ここで説明されている上記の手法(IPおよびUserAgent)を使用できます:個人情報の盗難を回避する方法
(PHP 6 で対処されている) 主な問題の 1 つは register_globals だと思います。現在、回避するために使用される標準的な方法の 1 つは、または配列register_globals
を使用することです。$_REQUEST
$_GET
$_POST
それを行うための「正しい」方法 (5.2 の時点では少しバグがありますが、6 の時点では安定しており、近日公開予定です) はフィルターを使用することです。
したがって、代わりに:
$username = $_POST["username"];
あなたがするだろう:
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
または単に:
$username = filter_input(INPUT_POST, 'username');
このセッション固定論文には、攻撃が来る可能性がある非常に優れたポインターがあります。ウィキペディアのセッション固定ページも参照してください。
私の経験では、IPアドレスを使用することは本当に最善のアイデアではありません。例えば; 私のオフィスには、負荷に応じて使用される 2 つの IP アドレスがあり、IP アドレスを使用すると常に問題が発生します。
代わりに、サーバー上のドメイン用に別のデータベースにセッションを保存することにしました。この方法では、ファイル システムの誰もそのセッション情報にアクセスできません。これは 3.0 より前の phpBB で非常に役に立ちました (その後修正されました) が、それでも良い考えだと思います。
PHPセッションとセキュリティ(セッションハイジャック以外)の主な問題は、使用している環境にあります。デフォルトでは、PHPはセッションデータをOSの一時ディレクトリにあるファイルに保存します。特別な考えや計画がなければ、これは誰でも読み取り可能なディレクトリであるため、すべてのセッション情報はサーバーにアクセスできるすべての人に公開されます。
複数のサーバーでセッションを維持する場合。その時点で、PHPをユーザーが処理するセッションに切り替えて、提供された関数を呼び出してセッションデータをCRUD(作成、読み取り、更新、削除)することをお勧めします。その時点で、セッション情報をデータベースまたはmemcacheのようなソリューションに保存して、すべてのアプリケーションサーバーがデータにアクセスできるようにすることができます。
共有サーバーを使用している場合は、独自のセッションを保存すると、ファイルシステムよりも制御しやすいデータベースに保存できるため、有利な場合があります。
これは非常に些細で明白ですが、使用後は必ずsession_destroyを実行してください。ユーザーが明示的にログアウトしないと、これを実装するのが難しい場合があるため、タイマーを設定してこれを行うことができます。
これは、setTimer() と clearTimer() に関する優れたチュートリアルです。
私はこのようにセッションを設定しました-
ログインページで:
$_SESSION['fingerprint'] = md5($_SERVER['HTTP_USER_AGENT'] . PHRASE . $_SERVER['REMOTE_ADDR']);
(構成ページで定義されたフレーズ)
次に、サイトの残りの部分にあるヘッダーで:
session_start();
if ($_SESSION['fingerprint'] != md5($_SERVER['HTTP_USER_AGENT'] . PHRASE . $_SERVER['REMOTE_ADDR'])) {
session_destroy();
header('Location: http://website login page/');
exit();
}
php.ini
session.cookie_httponly = 1
change session name from default PHPSESSID
eq Apache ヘッダーを追加:
X-XSS-Protection 1
セッションデータが安全であることを確認する必要があります。php.iniを確認するか、phpinfo()を使用すると、セッション設定を見つけることができます。_session.save_path_は、それらが保存されている場所を示します。
フォルダとその親の権限を確認してください。公開(/ tmp)したり、共有サーバー上の他のWebサイトからアクセスしたりしないでください。
引き続きphpセッションを使用する場合は、_session.save_path_を変更して他のフォルダーを使用するようにphpを設定するか、_session.save_handler_を変更してデータベースにデータを保存できます。
php.ini(一部のプロバイダーでは許可されています)またはapache + mod_phpの場合は、サイトのルートフォルダーにある.htaccessファイルで_session.save_path_を設定できる場合があります
php_value session.save_path "/home/example.com/html/session"
。実行時に_session_save_path()_を使用して設定することもできます。
Chris ShiflettのチュートリアルまたはZend_Session_SaveHandler_DbTableを確認して、代替セッションハンドラーを設定してください。
IP とユーザー エージェントの両方をチェックして、それらが変化するかどうかを確認します。
if ($_SESSION['user_agent'] != $_SERVER['HTTP_USER_AGENT']
|| $_SESSION['user_ip'] != $_SERVER['REMOTE_ADDR'])
{
//Something fishy is going on here?
}
session_set_save_handler()を使用すると、独自のセッション ハンドラを設定できます。たとえば、セッションをデータベースに保存できます。データベース セッション ハンドラの例については、php.net のコメントを参照してください。
DB セッションは、複数のサーバーがある場合にも適しています。それ以外の場合、ファイルベースのセッションを使用している場合は、各 Web サーバーがセッションを読み書きするために同じファイルシステムにアクセスできることを確認する必要があります。