わかりました、2つの個別の関連する問題があり、それぞれが異なる方法で処理されます。
セッション固定
これは、攻撃者がユーザーのセッションのセッション識別子を明示的に設定する場所です。通常、PHPでは、のようなURLを与えることで行われhttp://www.example.com/index...?session_name=sessionid
ます。攻撃者がURLをクライアントに渡したら、攻撃はセッションハイジャック攻撃と同じです。
セッションの固定を防ぐ方法はいくつかあります(それらすべてを実行してください)。
ファイルに設定session.use_trans_sid = 0
しますphp.ini
。これは、URLに識別子を含めないように、そして識別子のURLを読み取らないようにPHPに指示します。
ファイルに設定session.use_only_cookies = 1
しますphp.ini
。これにより、セッション識別子を持つURLを使用しないようにPHPに指示します。
セッションのステータスが変化するたびにセッションIDを再生成します。これは、次のいずれかを意味します。
- ユーザ認証
- セッションでの機密情報の保存
- セッションに関する変更
- 等...
セッションハイジャック
これは、攻撃者がセッション識別子を取得し、あたかもそのユーザーであるかのように要求を送信できる場所です。つまり、攻撃者は識別子を持っているため、サーバーに関しては有効なユーザーとほとんど区別がつきません。
セッションハイジャックを直接防止することはできません。ただし、ステップを入れて、使用を非常に困難かつ困難にすることができます。
強力なセッションハッシュ識別子を使用session.hash_function
しphp.ini
ます。PHP <5.3の場合はsession.hash_function = 1
、SHA1に設定します。PHP> = 5.3の場合は、session.hash_function = sha256
またはに設定しsession.hash_function = sha512
ます。
強力なハッシュを送信session.hash_bits_per_character
しphp.ini
ます。これをに設定しsession.hash_bits_per_character = 5
ます。これによってクラックが難しくなることはありませんが、攻撃者がセッション識別子を推測しようとするときに違いが出ます。IDは短くなりますが、より多くの文字を使用します。
追加のエントロピーを設定session.entropy_file
し、session.entropy_length
自分の中php.ini
のファイル。前者をsession.entropy_file = /dev/urandom
に、後者をエントロピーファイルから読み取るバイト数に設定しますsession.entropy_length = 256
。
セッションの名前をデフォルトのPHPSESSIDから変更します。これは、を呼び出すsession_name()
前に、最初のパラメータとして独自の識別子名を使用して呼び出すことで実現されますsession_start
。
あなたがいる場合は本当に被害妄想あなたもセッション名を回転させるが、(あなたが時間に依存させる場合、たとえば)あなたはこれを変更した場合、すべてのセッションが自動的に無効化されることを注意してください可能性があります。しかし、あなたのユースケースによっては、それはオプションかもしれません...
セッションIDを頻繁にローテーションします。私は(本当にそのレベルのセキュリティが必要でない限り)リクエストごとにこれを行うのではなく、ランダムな間隔で行います。攻撃者がセッションをハイジャックした場合、攻撃者がセッションを長時間使用できないようにするため、これを頻繁に変更する必要があります。
セッションにユーザーエージェントを$_SERVER['HTTP_USER_AGENT']
含めます。基本的に、セッションが開始したら、のような場所に保存し$_SESSION['user_agent']
ます。次に、後続の各リクエストで一致することを確認します。これは偽物である可能性があるため、100%信頼できるわけではないことに注意してください。
セッションにユーザーのIPアドレスを$_SERVER['REMOTE_ADDR']
含めます。基本的に、セッションが開始したら、のような場所に保存し$_SESSION['remote_ip']
ます。これは、ユーザーに複数のIPアドレスを使用している一部のISP(以前はAOLでしたなど)から問題になる可能性があります。しかし、それを使用すると、はるかに安全になります。攻撃者がIPアドレスを偽造する唯一の方法は、実際のユーザーとあなたの間のある時点でネットワークを危険にさらすことです。また、ネットワークを危険にさらした場合、ハイジャック(MITM攻撃など)よりもはるかに悪い結果をもたらす可能性があります。
セッションおよびブラウザー側に、増分して頻繁に比較するトークンを含めます。基本的に、リクエストごと$_SESSION['counter']++
にサーバー側で行います。また、ブラウザー側のJSで同じことを行う(ローカルストレージを使用)。次に、リクエストを送信するときに、トークンのナンスを取得し、ナンスがサーバー上で同じであることを確認します。これにより、攻撃者は正確なカウンターを持っていないため、ハイジャックされたセッションを検出できるはずです。そうした場合、2つのシステムが同じカウントを送信しており、1つが偽造されていると判断できます。これはすべてのアプリケーションで機能するわけではありませんが、問題を解決する1つの方法です。
二つについてのメモ
セッション固定とハイジャックの違いは、セッションIDがどのように侵害されたかだけです。固定では、識別子は攻撃者が事前に知っている値に設定されます。ハイジャックでは、ユーザーから推測または盗まれます。それ以外の場合、識別子が危険にさらされた後の2つの影響は同じです。
セッションIDの再生成
session_regenerate_id
古いセッションを使用してセッション識別子を再生成する場合は、常に削除する必要があります。これは、コアセッションハンドラーで透過的に行われます。ただし、を使用するsession_set_save_handler()
一部のカスタムセッションハンドラはこれを行わず、古いセッション識別子を攻撃する可能性があります。カスタムセッションハンドラーを使用している場合は、開いたIDを追跡し、保存したIDと異なる場合は、古いIDのIDを明示的に削除(または変更)することを確認してください。
デフォルトのセッションハンドラーを使用すると、を呼び出すだけで問題ありませんsession_regenerate_id(true)
。これにより、古いセッション情報が削除されます。古いIDは無効になり、攻撃者(またはそのことについては他の誰か)が使用しようとすると、新しいセッションが作成されます。ただし、カスタムセッションハンドラには注意してください。
セッションの破棄
セッションを破棄する場合(ログアウト時など)は、セッションを完全に破棄してください。これには、Cookieの設定解除が含まれます。使用session_destroy
:
function destroySession() {
$params = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000,
$params["path"], $params["domain"],
$params["secure"], $params["httponly"]
);
session_destroy();
}