質問
PHP で責任あるセッションのセキュリティを維持するためのガイドラインは何ですか?ウェブ上には情報があふれており、すべてが 1 か所に集まる時期が来ています。
解決
セッションを安全に保つために行うべきことがいくつかあります。
- ユーザーを認証するとき、または機密性の高い操作を実行するときに SSL を使用します。
- セキュリティ レベルが変更されるたびに (ログインなど)、セッション ID を再生成します。必要に応じて、リクエストごとにセッション ID を再生成することもできます。
- セッションをタイムアウトにする
- レジスタグローバルを使用しないでください
- 認証の詳細をサーバーに保存します。つまり、ユーザー名などの詳細を Cookie で送信しないでください。
- チェックしてください
$_SERVER['HTTP_USER_AGENT']
. 。これにより、セッション ハイジャックに対する小さな障壁が追加されます。IPアドレスも確認できます。しかし、これは、複数のインターネット接続などでの負荷分散により IP アドレスが変化するユーザーにとって問題を引き起こします (ここでの環境ではこれが当てはまります)。 - ファイル システム上のセッションへのアクセスをロックダウンするか、カスタム セッション処理を使用します。
- 機密性の高い操作の場合は、ログインしているユーザーに認証の詳細を再度提供するよう要求することを検討してください。
他のヒント
1 つのガイドラインは、電話をかけることです。 session_regenerate_id セッションのセキュリティ レベルが変更されるたびに。これはセッションハイジャックの防止に役立ちます。
私の 2 セント (またはそれ以上):
- 誰も信じない
- 入力をフィルターし、出力をエスケープします (Cookie、セッション データも入力です)
- XSS を避けます (HTML を適切な形式に保ち、以下を参照してください) PHPTAL または HTMLピュリファイアー)
- 多層防御
- データを公開しないでください
このテーマについては、小さいながらも優れた本があります。 基本的な PHP セキュリティ by Chris Shiflett.
基本的な PHP セキュリティ http://shiflett.org/images/essential-php-security-small.png
この本のホームページには、興味深いコード例とサンプルの章がいくつかあります。
ここで説明されている上記のテクニック (IP および UserAgent) を使用できます。 個人情報の盗難を避ける方法
大きな問題の 1 つは (PHP 6 で対処されています) 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['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
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 サーバーがセッションの読み取り/書き込みのために同じファイルシステムにアクセスできることを確認する必要があります。
セッション データが安全であることを確認する必要があります。php.ini を参照するか、phpinfo() を使用すると、セッション設定を見つけることができます。_session.save_path_ は、それらが保存される場所を示します。
フォルダーとその親の権限を確認してください。これはパブリック (/tmp) であってはならず、共有サーバー上の他の Web サイトからアクセス可能であってはなりません。
それでも php セッションを使用したい場合は、 _session.save_path_ を変更して別のフォルダーを使用するように php を設定するか、 _session.save_handler_ を変更してデータベースにデータを保存できます。
_session.save_path_ を php.ini (一部のプロバイダーでは許可されています) に設定するか、Apache + mod_php の場合はサイトのルート フォルダー内の .htaccess ファイルに設定できる場合があります。php_value session.save_path "/home/example.com/html/session"
. 。実行時に _session_save_path()_ を使用して設定することもできます。
チェック Chris Shiflett のチュートリアル または Zend_Session_SaveHandler_DbTable 代替セッションハンドラーを設定します。