web-dev-qa-db-ja.com

セッションハイジャックの防止

複数のクライアントが同じセッションIDを使用するのを防ぐにはどうすればよいですか?これは、Webサイトでのセッションハイジャックを防止するためにセキュリティのレイヤーを追加するためです。ハッカーが何らかの方法で別のユーザーのセッションIDを把握し、そのSIDでリクエストを行う場合、サーバー上で単一のSIDを共有している異なるクライアントがあることを検出して、ハイジャックの試みを拒否するにはどうすればよいですか?

[〜#〜] edit [〜#〜]

ステートレスHTTPプロトコルの制限のために私が求めていることは不可能であるという認識に至ったので、私は慎重に検討した後、Gumboの答えを受け入れました。おそらくHTTPの最も基本的な原理を忘れてしまいましたが、この質問について考えるのはささいなことです。

私が意味することを詳しく説明させてください:

ユーザーAがexample.comにログインすると、簡単にするためにランダムなセッションIDが与えられます。これを「abc123」とします。このセッションIDはCookieとしてクライアント側に保存され、サーバー側のセッションで検証されて、ログインしたユーザーが1つのWebページから別のWebページに移動してもログインしたままになります。 HTTPがステートレスでない場合、このCookieはもちろん存在する必要はありません。そのため、ユーザーBがユーザーAのSIDを盗み、値「abc123」を使用してコンピューターにCookieを作成した場合、ユーザーAのセッションは正常にハイジャックされますが、サーバーがそのユーザーBを正当に認識する方法はありません要求はユーザーAの要求とは異なるため、サーバーには要求を拒否する理由はありません。サーバー上で既にアクティブなセッションを一覧表示して、誰かがすでにアクティブなセッションにアクセスしているかどうかを確認しようとしても、同じユーザーではなく不正にセッションにアクセスしている別のユーザーであると判断する方法セッションIDを使用して既にログインしているが、それを使用して別のリクエストを行う(つまり、別のWebページに移動する)だけです。できません。ユーザーエージェントを確認しますか?スプーフィングされる可能性がありますが、それでも多層防御対策として優れています。 IPアドレス?正当な理由で変更できますが、IPアドレスをまったくチェックしない代わりに、IPの最初の2オクテットのようなものをチェックすることをお勧めします。通常、IP変更の最後の2オクテットしかありません。

結論として、セッションハイジャックからWebサイトを完全に保護することは決してできないと非難するのはステートレスHTTPですが、(Gumboが提供しているような)優れたプラクティスは、セッション攻撃の大部分を防ぐのに十分です。したがって、同じSIDの複数の要求を拒否することにより、セッションをハイジャックから保護しようとすることは単純に馬鹿げており、セッションの目的全体を無効にします。

63
hesson

残念ながら、本物のリクエストとは反対に攻撃者から発信されたリクエストを間違いなく識別する効果的な方法はありません。 IPアドレスやユーザーエージェントの特性などの対策をチェックするほとんどのプロパティは、信頼性が低い(IPアドレスが複数のリクエスト間で変更される可能性がある)か、簡単に偽造できる(例えばUser-Agentリクエストヘッダー)、したがって、望ましくない誤検知(つまり、本物のユーザースイッチIPアドレス)または誤検知(つまり、攻撃者が同じUser-Agentでリクエストを偽造できた) )。

そのため、セッションハイジャックを防ぐ最善の方法は、攻撃者が別のユーザーのセッションIDを見つけられないようにすることです。これは、(1)攻撃者が十分なエントロピーを使用して有効なセッションIDを推測できないように、(2)既知の攻撃によって有効なセッションIDを取得する他の方法がないように、アプリケーションとそのセッション管理を設計する必要があることを意味しますネットワーク通信のスニッフィング、クロスサイトスクリプティング、Refererなどの脆弱性.

ただし、次のことを行う必要があります。

それに加えて、古いセッションIDを無効にしながらセッションIDも再生成する必要があります( session_regenerate_id function )特定のセッション状態の変更後(ログイン後または認証/特権の変更後の真正性の確認など)、さらにこれを定期的に実行して、セッションハイジャック攻撃が成功するまでの時間を短縮できます。

76
Gumbo

このようなことができますか。

セッションIDをデータベースに保存します。また、そのセッションIDのIPアドレスとHTTP_USER_AGENTを保存します。一致するセッションIDを含むサーバーに要求が届いたら、スクリプトでどのエージェントとIPからのものかを確認します。

セッションの共通機能またはクラスを作成することにより、この基礎を機能させて、すべての要求が処理される前に検証されるようにすることができます。数マイクロ秒かかることはほとんどありません。しかし、多くのユーザーがサイトにアクセスしていて、セッションの膨大なデータベースがある場合、これはパフォーマンスの問題ではありません。しかし、それは確かに=>再生成セッションの使用のような他の方法と比較して非常に安全です。

セッションIDの再生成では、セッションハイジャックの可能性はほとんどありません。

ユーザーのセッションIDがコピーされ、そのユーザーがしばらく動作していないかアクティブではなく、新しいセッションIDを再生成するように要求する古いセッションIDのサーバーへの要求がないと仮定します。次に、セッションIDがハイジャックされた場合、ハッカーはそのセッションIDを使用し、そのIDでサーバーにリクエストを行い、サーバーは再生成されたセッションIDで応答し、ハッカーがサービスを使用できるようにします。実際のユーザーは、再生成されたIDと、リクエストで渡されるリクエストセッションIDが不明なため、操作できなくなります。完全になくなった。

どこか間違っているなら修正してください。

4
kanchan

セッションハイジャックに対する多くの標準的な防御策があります。それらの1つは、各セッションを単一のIPアドレスに一致させることです。

その他のスキーム は、以下から生成されたHMACを使用できます。

  • クライアントのIPのネットワークアドレス
  • クライアントによって送信されたユーザーエージェントヘッダー
  • sID
  • サーバーに保存された秘密鍵

IPのネットワークアドレスのみが使用される理由は、ユーザーがパブリックプロキシの背後にいる場合です。この場合、IPアドレスはリクエストごとに変更できますが、ネットワークアドレスは同じままです。

もちろん、本当に安全であるためには、最初に攻撃者になりすましてSIDを傍受できないように、すべての要求に対してSSLを強制する必要があります。しかし、すべてのサイトがこれを行うわけではありません(:: cough :: Stack Overflow :: cough ::)。

2
Lèse majesté

簡単な実装の1つは、ログインしたユーザーとしてデータベースにテーブルを作成し、ログイン時にそのテーブルをユーザー名と彼のSIDで更新することで実行できます。これにより、ログアウト時に同じユーザーとして他のログインができなくなります。データベースのログインデータを削除する簡単なクエリを実行するだけで、これは同時にurウェブサイトのログインユーザーを追跡するためにも使用できます。

1
Ratan Kumar

セッションハイジャックは深刻な脅威です。トランザクションを含む高度なアプリケーション用のセキュアソケットレイヤーを使用するか、上記のCookie、セッションタイムアウト、IDの再生成などの簡単な手法を使用して処理する必要があります。
インターネットが誕生したとき、HTTP通信はステートレスになるように設計されていました。つまり、2つのエンティティ間の接続は、要求がサーバーに送信されるのに必要な短時間だけ存在し、結果の応答はクライアントに返されます。ここに、ハッカーがセッションをハイジャックするために従ういくつかの方法があります

  • ネットワーク盗聴
  • 意図しない露出
  • 転送、プロキシ、フィッシング
  • 逆プロキシ

常にSSLを推奨Secure Sockets Layer
php-iniのグローバル設定を上書きするには、スクリプトの開始時に次のini_set()ディレクティブにもcookiesを使用します。

ini_set( 'session.use_only_cookies', TRUE );                
ini_set( 'session.use_trans_sid', FALSE );

セッションタイムアウトとセッション再生成IDを使用します

<?php
// regenerate session on successful login
if ( !empty( $_POST['password'] ) && $_POST['password'] === $password )         
{       
 // if authenticated, generate a new random session ID
  session_regenerate_id();

 // set session to authenticated
  $_SESSION['auth'] = TRUE;

 // redirect to make the new session ID live

 header( 'Location: ' . $_SERVER['SCRIPT_NAME'] );
}                   
// take some action
?>
1

明らかに、ブラウザでセッションCookieを設定すると、そのCookieはリクエストで送信されます。リクエストが来ると、サーバーはデータベース内のセッションIDをチェックし、アクセスを許可します。それを防ぐために、エージェントとIPを保存することが重要であるため、サーバーをチェックする前に、セッションアクセスがハイジャック可能な一意のセッションIDではなく、一意のクライアントに許可されていることを確認します。

1
kanchan

私の見解では、ユーザーがログインするときにデータベースにセッションIDを保存し、ログインする前にすべてのユーザーを確認できます。ユーザーがログアウトするときにデータベースに保存した同じセッションIDを削除します。各ユーザーのセッションIDを簡単に見つけることができます。

1
Sk MiRaj

コーディングの部分についてよく知りません。そのため、これを行うアルゴリズムを教えてください。ユーザーがLANネットワークからセッションIDをスニッフィングする場合(提供されたユーザーと攻撃者が同じLANにいる場合)、SSLなどを設定するか、セッションCookieをセキュアに設定し、httpOnlyは機能しません。

そのため、ユーザーがアプリケーションに正常にログインしたら、Webアプリケーションの各ページに一意のトークンを設定し、サーバー側でこれを追跡できます。そのため、有効なユーザーが特定のページにアクセスするリクエストを送信すると、そのページのトークンもサーバー側に送信されます。トークンは特定のセッションのユーザーに対して一意であるため、攻撃者がセッションIDを取得できたとしても、サーバーに有効なトークンを提供できないため、ユーザーセッションをハイジャックできません。

0
Anandu M Das

@Anandu M Das:

あなたが言及しているのは、各セッションIDでのセッショントークンの使用だと思います。このサイトでは、セッションでのトークンの使用について説明できます。

https://blog.whitehatsec.com/tag/session-token/

セッショントークンはXSS攻撃によって簡単に侵害されますが、これは決して使用されるべきではないという意味ではありません。サーバーのセキュリティ脆弱性によって何かが危うくなり、メソッドのせいではなく、その脆弱性を導入したプログラマーのせいであるなら(ヘッソンとルークが指摘した点を強調するため)、私はそれに直面しようとします。

適切なセキュリティ規則と実践に従い、サイトをSQLインジェクション、XSSから保護し、すべてのセッションをHTTPSで管理する必要がある場合、セッション内に保存されたサーバー側トークンを使用してCSRFからの潜在的な攻撃を簡単に管理できます。また、ユーザーがセッションを操作するたびに更新されます(送信される$ _POSTなど)。また、セッションやそのコンテンツをエンコードしても、URLに保存しないでください。

ユーザーのセキュリティが最も重要な場合(そうあるべきです)、セッショントークンを使用すると、セッションセキュリティを損なうことなく、より優れた、またはより高度な機能を提供できます。

0
user253780