Skip to main content

Session cheatsheet

Session_Management_Cheat_Sheet

セッション管理チートシート(翻訳しただけ)

導入

Web認証、セッション管理、アクセス制御 Webセッションとは、同じユーザーに関連付けられたネットワークHTTP要求と応答のトランザクションのシーケンスです。
最新の複雑なWebアプリケーションでは、複数の要求が続く間、各ユーザーに関する情報やステータスを保持する必要があります。そのため、セッションでは、アクセス権やローカリゼーション設定などの変数を確立する機能が提供されます。これらの変数は、セッションの期間中、ユーザーがWebアプリケーションと行うすべてのやり取りに適用されます。

Webアプリケーションは、最初のユーザー リクエストの後に匿名ユーザーを追跡するためのセッションを作成できます。たとえば、ユーザーの言語設定を維持する場合などです。さらに、Webアプリケーションは、ユーザーが認証されるとセッションを使用します。これにより、後続のリクエストでユーザーを識別できるだけでなく、セキュリティ アクセス制御、ユーザーのプライベート データへの承認済みアクセスを適用し、アプリケーションの使いやすさを向上させることができます。したがって、現在のWebアプリケーションは、認証前と認証後の両方でセッション機能を提供できます。

認証されたセッションが確立されると、セッションID (またはトークン) は、ユーザー名とパスワード、パスフレーズ、ワンタイム パスワード (OTP)、クライアント ベースのデジタル証明書、スマート カード、または生体認証 (指紋や目の網膜など) など、アプリケーションで使用される最も強力な認証方法と一時的に同等になります。OWASP認証チート シートを参照してください。

HTTPはステートレス プロトコル ( RFC2616セクション5) であり、各リクエストとレスポンスのペアは他のWebのやり取りから独立しています。したがって、セッションの概念を導入するには、Webアプリケーションで一般的に使用できる認証モジュールとアクセス制御 (または承認) モジュールの両方をリンクするセッション管理機能を実装する必要があります。

セッションダイアグラム

セッションIDまたはトークンは、ユーザー認証資格情報 (ユーザー セッションの形式) を、ユーザー HTTPトラフィックおよびWebアプリケーションによって適用される適切なアクセス制御にバインドします。最新のWebアプリケーションにおけるこれら3つのコンポーネント (認証、セッション管理、アクセス制御) の複雑さ、および実装とバインドがWeb開発者の手に委ねられているという事実 (Web開発フレームワークはこれらのモジュール間の厳密な関係を提供しないため) により、安全なセッション管理モジュールの実装は非常に困難になっています。

セッションIDの開示、キャプチャ、予測、ブルート フォース、または固定は、セッション ハイジャック (またはサイドジャック) 攻撃につながり、攻撃者はWebアプリケーションで被害者のユーザーを完全に偽装できます。攻撃者は、標的型と汎用型の2種類のセッション ハイジャック攻撃を実行できます。標的型攻撃の場合、攻撃者の目的は、特定の (または特権を持つ) Webアプリケーションの被害者のユーザーになりすますことです。汎用攻撃の場合、攻撃者の目的は、Webアプリケーションで任意の有効または正当なユーザーになりすます (またはアクセスする) ことです。

セッションIDプロパティ

認証された状態を維持し、Webアプリケーション内でのユーザーの進行状況を追跡するために、アプリケーションは、セッション作成時に割り当てられ、セッション期間中にユーザーとWebアプリケーションによって共有および交換されるセッション識別子(セッションIDまたはトークン) をユーザーに提供します (セッションIDは、すべてのHTTP要求で送信されます)。セッションIDはペアですname=value。

安全なセッションIDを実装するためには、識別子 (IDまたはトークン) の生成が次のプロパティを満たす必要があります。

セッションID名のフィンガープリンティング¶ セッションIDで使用される名前は、過度に説明的なものや、IDの目的や意味について不必要な詳細を提供するものであってはなりません。

最も一般的なWebアプリケーション開発フレームワークで使用されるセッションID名は、(PHP)、(J2EE)、( ColdFusion )、 (ASP .NET)など、簡単にフィンガープリントできます。したがって、セッションID名から、Webアプリケーションで使用されるテクノロジとプログラミング言語が明らかになる可能性があります。PHPSESSIDJSESSIONIDCFIDCFTOKENASP.NET_SessionId

Web開発フレームワークのデフォルトのセッションID名を、 などの一般的な名前に変更することをお勧めしますid。

セッションIDの長さ

セッションIDは、ブルート フォース攻撃 (攻撃者がID値の全範囲を調べて有効なセッションの存在を確認できる) を防ぐのに十分な長さである必要があります。

セッションIDの長さは少なくともである必要があります128 bits (16 bytes)。

注記:

128ビットのセッションIDの長さは、次のセクション「セッションIDエントロピー」で行われた仮定に基づいて参考として提供されています。ただし、他の実装要因がその強度に影響を与える可能性があるため、この数値は絶対的な最小値として考慮されるべきではありません。 たとえば、Microsoft ASP.NETセッションIDなどのよく知られた実装があります。「ASP .NETセッションIDは、aからzまでの小文字と0から5までの数字で構成される24文字の文字列にエンコードされた、ランダムに生成された数値です。」 非常に優れた有効エントロピーを提供できるため、推測やブルート フォース攻撃を回避するのに十分な長さであると考えられます。 セッションIDエントロピー¶ 攻撃者が統計分析技術を使用して有効なセッションのIDを推測または予測できる推測攻撃を防ぐために、セッションIDは予測不可能 (十分にランダム) である必要があります。この目的のために、優れたCSPRNG (暗号的に安全な疑似乱数ジェネレーター) を使用する必要があります。

セッションID値は少なくとも64 bitsエントロピーを提供する必要があります (適切なPRNGが使用されている場合、この値はセッションIDの長さの半分になると推定されます)。

さらに、ランダムなセッションIDだけでは不十分です。重複したIDを避けるために、セッションIDは一意である必要があります。ランダムなセッションIDは、現在のセッションIDスペースに既に存在してはなりません。

注記:

セッションIDエントロピーは、Webアプリケーションに一般的に存在する同時アクティブ セッションの数、絶対セッション有効期限のタイムアウト、攻撃者が1秒あたりに実行できるセッションID推測の数、およびターゲットWebアプリケーションがサポートできるセッションID推測の数など、他の外部の測定が難しい要因によって実際に影響を受けます。 エントロピーが のセッションID64 bitsが使用される場合、Webアプリケーションで100,000の有効な同時セッションが利用可能で、攻撃者が1秒あたり10,000回の推測を試みることができると仮定すると、攻撃者は有効なセッションIDを推測するのに292年以上かかることが予想されます。 詳細はここをご覧ください。 セッションIDの内容 (または値)¶ 情報漏洩攻撃を防ぐために、セッションIDの内容 (または値) は無意味である必要があります。情報漏洩攻撃では、攻撃者がIDの内容をデコードし、ユーザー、セッション、またはWebアプリケーションの内部動作の詳細を抽出できます。

セッションIDはクライアント側の単なる識別子である必要があり、その値には機密情報や個人を特定できる情報 (PII) を含めることはできません。PIIの詳細については、Wikipediaまたはこの投稿を参照してください。

セッションIDに関連付けられた意味とビジネス ロジックまたはアプリケーション ロジックは、サーバー側、具体的にはセッション オブジェクトまたはセッション管理データベースまたはリポジトリに保存する必要があります。

保存される情報には、クライアントIPアドレス、ユーザー エージェント、電子メール、ユーザー名、ユーザー ID、ロール、権限レベル、アクセス権、言語設定、アカウントID、現在の状態、最終ログイン、セッション タイムアウト、その他の内部セッションの詳細が含まれます。セッション オブジェクトとプロパティにクレジットカード番号などの機密情報が含まれている場合は、セッション管理リポジトリを適切に暗号化して保護する必要があります。

言語またはフレームワークによって作成されたセッションIDを使用することをお勧めします。独自のセッションIDを作成する必要がある場合は、少なくとも128ビットのサイズの暗号的に安全な疑似乱数ジェネレーター (CSPRNG) を使用して、各セッションIDが一意であることを確認してください。

セッション管理の実装¶ セッション管理の実装は、ユーザーとWebアプリケーションの間でセッションIDを共有し、継続的に交換するために使用される交換メカニズムを定義します。Webアプリケーション内でセッション状態を維持するために、HTTPには、Cookie (標準HTTPヘッダー)、URLパラメーター (URL書き換え - RFC2396 )、GET要求のURL引数、POST要求の本文引数 (隠しフォーム フィールド (HTMLフォーム) など)、独自のHTTPヘッダーなど、複数のメカニズムが用意されています。

推奨されるセッションID交換メカニズムでは、トークンの有効期限や時刻、細かい使用制限などの高度なトークン プロパティを定義できる必要があります。これが、Cookie (RFC 2109、2965、6265) が最も広く使用されているセッションID交換メカニズムの1つであり、他の方法では利用できない高度な機能を提供する理由の1つです。

IDがURLに含まれているような特定のセッションID交換メカニズムを使用すると、セッションIDが (Webリンクやログ、Webブラウザーの履歴やブックマーク、Refererヘッダー、検索エンジンなどで) 公開される可能性があり、また、IDの操作やセッション固定攻撃などの他の攻撃も容易になる可能性があります。

組み込みセッション管理実装¶ J2EE、ASP .NET、PHPなどのWeb開発フレームワークは、独自のセッション管理機能と関連する実装を提供します。これらの組み込みフレームワークは世界中の複数のWeb環境で使用されており、Webアプリケーションのセキュリティおよび開発コミュニティによって長年にわたってテストされているため、自作のフレームワークをゼロから構築するのではなく、これらの組み込みフレームワークを使用することをお勧めします。

ただし、これらのフレームワークは過去に脆弱性や弱点も抱えていることに留意してください。そのため、既知の脆弱性がすべて修正されている可能性のある最新バージョンを常に使用し、このドキュメントに記載されている推奨事項に従ってデフォルト構成を確認して変更し、セキュリティを強化することをお勧めします。

セッションIDを一時的に保存するためにセッション管理メカニズムによって使用されるストレージ機能またはリポジトリは、ローカルまたはリモートでの偶発的な漏洩や不正アクセスからセッションIDを保護するために安全である必要があります。

使用されるセッションID交換メカニズムと受け入れられるセッションID交換メカニズム¶ Webアプリケーションは、セッションID交換管理にCookieを使用する必要があります。ユーザーがURLパラメータなどの別の交換メカニズムを使用してセッションIDを送信した場合、Webアプリケーションはセッション固定を阻止する防御戦略の一環として、そのIDを受け入れないようにする必要があります。

注記:

WebアプリケーションがデフォルトのセッションID交換メカニズムとしてCookieを使用する場合でも、他の交換メカニズムも受け入れる場合があります。 したがって、セッションIDを処理および管理する際に、Webアプリケーションが現在受け入れているさまざまなメカニズムをすべて徹底的にテストして確認し、受け入れられるセッションID追跡メカニズムをCookieだけに制限する必要があります。 過去には、一部のWebアプリケーションでは、特定の条件 (たとえば、CookieをサポートしていないWebクライアントの識別や、ユーザーのプライバシーに関する懸念からCookieを受け入れないなど) が満たされた場合、URLパラメータを使用したり、CookieからURLパラメータに切り替えたり (自動URL書き換えによって) していました。 トランスポート層セキュリティ¶ ネットワーク トラフィックでの能動的な盗聴や受動的な漏洩からセッションID交換を保護するには、ユーザー資格情報が交換される認証プロセスだけでなく、Webセッション全体で暗号化されたHTTPS (TLS) 接続を使用することが不可欠です。これは、クライアントがサポートしているHTTP Strict Transport Security (HSTS)によって軽減される可能性があります。

さらに、セッションIDが暗号化されたチャネルを通じてのみ交換されるようにするには、 Secure Cookie属性を使用する必要があります。暗号化された通信チャネルを使用すると、攻撃者がWebトラフィックを傍受して操作し、被害者のWebブラウザにセッションIDを挿入 (または修正) するセッション固定攻撃からセッションを保護することもできます (こちらとこちらを参照)。

次のベスト プラクティス セットは、セッションID (特にCookieが使用される場合) を保護し、Webアプリケーション内でのHTTPSの統合を支援することに重点を置いています。

特定のセッションをHTTPからHTTPSに、またはその逆に切り替えないでください。切り替えると、セッションIDがネットワークを通じて暗号化されずに公開されます。 HTTPSにリダイレクトする場合は、リダイレクトが発生した後にCookieが設定または再生成されることを確認します。 同じページ内または同じドメイン内の暗号化されたコンテンツと暗号化されていないコンテンツ (HTMLページ、画像、CSS、JavaScriptファイルなど) を混在させないでください。 可能であれば、同じホストから暗号化されていない公開コンテンツと暗号化された非公開コンテンツを提供することは避けてください。安全でないコンテンツが必要な場合は、別の安全でないドメインでホストすることを検討してください。 HTTPS接続を強制するには、HTTP Strict Transport Security (HSTS)を実装します。 TLSを安全に実装するためのより一般的なガイダンスについては、OWASP Transport Layer Security Cheat Sheetを参照してください。

TLSはセッションIDの予測、ブルート フォース、クライアント側の改ざんや固定に対しては保護を提供しないことを強調しておくことが重要です。ただし、中間者攻撃によってセッションIDを傍受または盗用する攻撃者に対しては効果的な保護を提供します。

クッキー¶ クッキーに基づくセッションID交換メカニズムは、セッションIDの交換を保護するために使用できるクッキー属性の形式で複数のセキュリティ機能を提供します。

セキュア属性¶ CookieSecure属性は、Webブラウザに、暗号化されたHTTPS (SSL/TLS) 接続を介してのみCookieを送信するように指示します。このセッション保護メカニズムは、MitM (中間者) 攻撃によるセッションIDの漏洩を防ぐために必須です。これにより、攻撃者がWebブラウザのトラフィックからセッションIDを簡単に取得できなくなります。

Webアプリケーションが通信にHTTPSのみを使用するように強制しても (Webアプリケーション ホストでポートTCP/80、HTTPが閉じられている場合でも)、CookieがSecure設定されていない場合はセッションIDの漏洩を防ぐことはできません。Webブラウザは、暗号化されていないHTTP接続を介してセッションIDを漏洩するように騙される可能性があります。攻撃者は、被害者のユーザー トラフィックを傍受して操作し、Webアプリケーションへの暗号化されていないHTTP参照を挿入して、WebブラウザにセッションIDを平文で送信させるように強制できます。

参照: SecureFlag

HttpOnly属性¶ cookieHttpOnly属性は、Webブラウザに、スクリプト (JavaScriptやVBscriptなど) がDOM document.cookieオブジェクトを介してcookieにアクセスできないように指示します。このセッションID保護は、XSS攻撃によるセッションIDの盗難を防ぐために必須です。ただし、XSS攻撃がCSRF攻撃と組み合わされた場合、ブラウザはリクエストの送信時に常にcookieを含めるため、Webアプリケーションに送信されるリクエストにはセッションcookieが含まれます。cookieはHttpOnlycookieの機密性のみを保護します。攻撃者は、XSS攻撃のコンテキスト外で、cookieをオフラインで使用することはできません。

OWASP XSS (クロスサイトスクリプティング) 防止チートシートを参照してください。

参照: HttpOnly

SameSite属性¶ SameSiteは、ブラウザがクロスサイト リクエストでSameSiteフラグ付きCookieを送信するのを防ぐCookie属性を定義します。主な目的は、クロスオリジン情報漏洩のリスクを軽減し、クロスサイト リクエスト フォージェリ攻撃に対する保護を提供することです。

参照: SameSite

ドメインとパス属性¶ cookieDomain属性は、 Webブラウザに、指定されたドメインとすべてのサブドメインにのみcookieを送信するように指示します。属性が設定されていない場合、デフォルトではcookieはオリジン サーバーにのみ送信されます。cookiePath属性は、 Webブラウザに、Webアプリケーション内の指定されたディレクトリまたはサブディレクトリ (またはパスまたはリソース) にのみcookieを送信するように指示します。属性が設定されていない場合、デフォルトではcookieは、要求されcookieが設定されているリソースのディレクトリ (またはパス) にのみ送信されます。

これら2つの属性には、狭い範囲または制限された範囲を使用することをお勧めします。この方法では、属性をDomain設定せず (Cookieを元のサーバーのみに制限)、PathセッションIDを使用するWebアプリケーション パスに属性を可能な限り制限して設定する必要があります。

Domain属性をなどの許容度が高すぎる値に設定すると、example.com攻撃者は同じドメインに属する異なるホストやWebアプリケーション間のセッションIDに対して攻撃を仕掛けることができます。これはクロスサブドメインCookieと呼ばれます。たとえば、 の脆弱性により、www.example.com攻撃者はからセッションIDにアクセスできる可能性がありますsecure.example.com。

さらに、同じドメイン上でセキュリティ レベルの異なるWebアプリケーションを混在させないことが推奨されます。いずれかのWebアプリケーションに脆弱性があると、攻撃者は、セッション固定攻撃で使用できる手法であるpermissive属性(Domainなどexample.com) を使用して、同じドメイン上の別のWebアプリケーションのセッションIDを設定できるようになります。

このPath属性により、同じホスト上の異なるパスを使用する異なるWebアプリケーション間でセッションIDを分離できますが、同じホスト上で異なるWebアプリケーション (特にセキュリティ レベルやスコープが異なるもの) を実行しないことを強くお勧めします。これらのアプリケーションは、オブジェクトなどの他の方法を使用してセッションIDにアクセスできますdocument.cookie。また、どのWebアプリケーションでも、そのホスト上の任意のパスにCookieを設定できます。

CookieはDNSスプーフィング/ハイジャック/ポイズニング攻撃に対して脆弱であり、攻撃者はDNS解決を操作して、Webブラウザに特定のホストまたはドメインのセッションIDを開示させることができます。

有効期限と最大有効期間の属性¶ クッキーに基づくセッション管理メカニズムでは、非永続的 (またはセッション) クッキーと永続的クッキーの2種類のクッキーを使用できます。クッキーがMax-Age( より優先されるExpires) またはExpires属性を提示する場合、そのクッキーは永続的クッキーとみなされ、有効期限までWebブラウザによってディスクに保存されます。

通常、認証後にユーザーを追跡するセッション管理機能では、非永続的なCookieが使用されます。これにより、現在のWebブラウザー インスタンスが閉じられると、クライアントからセッションが強制的に消えます。したがって、セッション管理の目的では非永続的なCookieを使用することを強くお勧めします。これにより、セッションIDがWebクライアント キャッシュに長期間残って攻撃者が取得するのを防ぐことができます。

機密情報が永続的に保存されないようにし、暗号化し、必要な期間のみ保存することで、機密情報が漏洩しないようにします。 クッキー操作による不正な活動が行われないようにする 安全でない方法で誤ってネットワーク経由で送信されないように、セキュアフラグが設定されていることを確認します。 アプリケーションコード内のすべての状態遷移が適切にクッキーをチェックし、その使用を強制しているかどうかを確認します。 機密データがクッキーに保存されている場合は、クッキー全体を暗号化する必要があります。 アプリケーションで使用されるすべてのCookie、その名前、および必要な理由を定義します。 HTML5ウェブストレージAPI¶ Webハイパーテキスト アプリケーション技術ワーキング グループ (WHATWG) は、クライアント側で名前と値のペアを保存するためのメカニズムとして、 HTML5 WebストレージAPIlocalStorageおよびについて説明しています。HTTPクッキーとは異なり、およびの内容は、ブラウザによる要求または応答内で自動的に共有されず、クライアント側でデータを保存するために使用されます。sessionStoragelocalStoragesessionStorage

ローカルストレージAPI¶ 範囲¶ APIを使用して保存されたデータはlocalStorage、同じオリジンから読み込まれたページからアクセスできます。オリジンは、スキーム ( https://)、ホスト ( example.com)、ポート ( 443)、およびドメイン/レルム ( ) として定義されます。これにより、Cookieのフラグをexample.com使用して実現されるのと同様のデータへのアクセスが提供されます。つまり、 から保存されたデータはを介して取得できません。別のウィンドウ/スレッドからの同時アクセスの可能性があるため、 を使用して保存されたデータは共有アクセスの問題 (競合状態など) の影響を受けやすく、非ロックと見なす必要があります ( Web Storage API仕様)。securehttpshttplocalStorage

間隔¶ APIを使用して保存されたデータはlocalStorageブラウジング セッション全体にわたって保持され、他のシステム ユーザーがアクセスできる期間が延長されます。

オフラインアクセス¶ 標準ではlocalStorage保存時にデータを暗号化する必要がないため、ディスクからこのデータに直接アクセスできる可能性があります。

使用事例¶ WHATWGは、複数のウィンドウやタブ、複数のセッションにわたってアクセスする必要があるデータや、パフォーマンス上の理由から大容量 (数メガバイト) のデータを格納する必要がある場合にを使用することを提案してlocalStorageいます。

セッションストレージAPI¶ 範囲¶ APIsessionStorageは、呼び出し元のウィンドウ コンテキスト内にデータを保存します。つまり、タブ1はタブ2から保存されたデータにアクセスできません。また、APIと同様にlocalStorage、APIを使用して保存されたデータsessionStorageは、スキーム ( https://)、ホスト ( example.com)、ポート ( )、443およびドメイン/領域 ( ) として定義される同じオリジンから読み込まれたページからアクセスできます。これにより、Cookieの フラグexample.comを使用することによって実現されるのと同様のデータ アクセスが提供されます。つまり、 から保存されたデータはを介して取得できません。securehttpshttp

間隔¶ APIsessionStorageは、現在のブラウジング セッションの期間中のみデータを保存します。タブが閉じられると、そのデータは取得できなくなります。ただし、ブラウザ タブを再利用したり開いたままにしたりしても、必ずしもアクセスが妨げられるわけではありません。また、ガベージ コレクション イベントが発生するまで、データがメモリ内に残ることもあります。

オフラインアクセス¶ 標準ではsessionStorage保存時にデータを暗号化する必要がないため、ディスクからこのデータに直接アクセスできる可能性があります。

使用事例¶ WHATWGは、チケット予約の詳細など、ワークフローの1つのインスタンスに関連するデータに対して、他のタブで複数のワークフローを同時に実行できる場合にを使用することを提案していますsessionStorage。ウィンドウ/タブにバインドされた性質により、別々のタブのワークフロー間でデータが漏洩することはありません。

参考文献¶ ウェブストレージAPI ローカルストレージAPI セッションストレージAPI WHATWG Webストレージ仕様 ウェブワーカー¶ Web Workersは、現在のウィンドウとは別のグローバル コンテキストでJavaScriptコードを実行します。メイン実行ウィンドウとの通信チャネルが存在し、これを と呼びますMessageChannel。

使用事例

Web Workersは、ページの更新後もストレージの永続性が要求されない場合に、ブラウザーに (セッション) シークレットを保存する代替手段です。Web Workersが安全なブラウザー ストレージを提供するには、シークレットを必要とするコードはすべてWeb Workers内に存在し、シークレットがメイン ウィンドウ コンテキストに送信されないようにする必要があります。

Web Workerのメモリ内にシークレットを保存すると、HttpOnly Cookieと同じセキュリティ保証が提供されます。つまり、シークレットの機密性が保護されます。ただし、XSS攻撃を使用してWeb Workerにメッセージを送信し、シークレットを必要とする操作を実行することは可能です。Web Workerは、操作の結果をメイン実行スレッドに返します。

HttpOnly Cookieと比較したWeb Worker実装の利点は、Web Workerでは分離されたJavaScriptコードがシークレットにアクセスできることです。一方、HttpOnly CookieはどのJavaScriptからもアクセスできません。フロントエンドのJavaScriptコードがシークレットにアクセスする必要がある場合、Web Worker実装はシークレットの機密性を保持する唯一のブラウザー ストレージ オプションです。

セッションIDのライフサイクル

セッションIDの生成と検証: 許容型と厳密型のセッション管理¶ セッション固定の脆弱性に関連するWebアプリケーションのセッション管理メカニズムには、許容型と厳密型の2種類があります。許容型メカニズムでは、Webアプリケーションは最初にユーザーが設定したセッションID値を有効として受け入れ、新しいセッションを作成できます。一方、厳密型メカニズムでは、Webアプリケーションが以前に生成したセッションID値のみを受け入れるように強制します。

セッション トークンは、可能な場合はWebサーバーによって処理されるか、暗号化された安全な乱数ジェネレータによって生成される必要があります。

現在使用されている最も一般的なメカニズムはstrict(より安全)ですが、PHPのデフォルトはpermissiveです。開発者は、特定の状況下でWebアプリケーションがpermissiveメカニズムを使用しないようにする必要があります。Webアプリケーションは、生成したことのないセッションIDを決して受け入れてはなりません。セッションIDを受け取った場合は、新しい有効なセッションIDを生成してユーザーに提供する必要があります。さらに、このシナリオは疑わしいアクティビティとして検出され、アラートが生成される必要があります。

セッションIDを他のユーザー入力と同様に管理する¶ セッションIDは、Webアプリケーションによって処理される他のユーザー入力と同様に信頼できないものとみなされ、徹底的に検証および確認される必要があります。使用されるセッション管理メカニズムに応じて、セッションIDはGETまたはPOSTパラメータ、URL、またはHTTPヘッダー (例: クッキー) で受信されます。Webアプリケーションが無効なセッションID値を処理前に検証およびフィルター処理しない場合、セッションIDがリレーショナル データベースに保存されている場合はSQLインジェクション、セッションIDがWebアプリケーションによって保存され、後で反映される場合は永続的なXSSなど、他のWebの脆弱性を悪用される可能性があります。

権限レベルの変更後にセッションIDを更新する¶ 関連するユーザー セッション内で権限レベルが変更された後は、WebアプリケーションによってセッションIDを更新または再生成する必要があります。セッションIDの再生成が必須となる最も一般的なシナリオは、認証プロセス中であり、ユーザーの権限レベルが認証されていない (または匿名) 状態から認証済みの状態に変更されますが、場合によってはまだ承認されていない状態になることがあります。考慮すべき一般的なシナリオには、パスワードの変更、権限の変更、またはWebアプリケーション内での通常のユーザー ロールから管理者ロールへの切り替えなどがあります。Webアプリケーションのすべての機密ページについては、以前のセッションIDを無視し、保護されたリソースに対して受信したすべての新しい要求に現在のセッションIDのみを割り当て、古いセッションIDまたは以前のセッションIDを破棄する必要があります。

最も一般的なWeb開発フレームワークは、request.getSession(true)& HttpSession.invalidate()(J2EE)、Session.Abandon()& Response.Cookies.Add(new...)(ASP .NET)、session_start()& session_regenerate_id(true)(PHP) など、セッションIDを更新するためのセッション関数とメソッドを提供します。

セッションIDの再生成は、セッション固定攻撃を防ぐために必須です。セッション固定攻撃では、攻撃者は、他のほとんどのセッションベースの攻撃のように被害者のセッションIDを収集するのではなく、HTTPまたはHTTPSの使用とは無関係に、被害者のユーザーのWebブラウザーにセッションIDを設定します。この保護により、HTTPレスポンス分割やXSSなど、セッション固定攻撃を開始するためにも使用される可能性がある他のWebベースの脆弱性の影響が軽減されます (こちらとこちらを参照)。

補足的な推奨事項としては、認証前と認証後に異なるセッションIDまたはトークン名 (またはセッションIDのセット) を使用することです。これにより、Webアプリケーションは、両方の状態間でユーザー セッションが公開されたりバインドされたりするリスクなしに、匿名ユーザーと認証済みユーザーを追跡できます。

複数のCookieを使用する場合の考慮事項¶ WebアプリケーションがセッションID交換メカニズムとしてCookieを使用し、特定のセッションに複数のCookieが設定されている場合、Webアプリケーションはユーザー セッションへのアクセスを許可する前に、すべてのCookieを検証し (それらの間の関係を強制し) る必要があります。

ウェブ アプリケーションがHTTP経由で認証前のユーザー Cookieを設定して、認証されていない (または匿名の) ユーザーを追跡することは非常に一般的です。ユーザーがウェブ アプリケーションで認証されると、新しい認証後の安全なCookieがHTTPS経由で設定され、両方のCookieとユーザー セッション間のバインディングが確立されます。ウェブ アプリケーションが認証されたセッションの両方のCookieを検証しない場合、攻撃者は認証前の保護されていないCookieを利用して、認証されたユーザー セッションにアクセスできます (こことここを参照)。

Webアプリケーションでは、同じWebアプリケーション内の異なるパスまたはドメイン スコープに同じCookie名を使用しないようにする必要があります。これは、ソリューションの複雑さが増し、スコープの問題が発生する可能性があるためです。

セッションの有効期限

攻撃者がアクティブなセッションに対して攻撃を仕掛け、それらを乗っ取る期間を最小限に抑えるためには、すべてのセッションに有効期限のタイムアウトを設定し、セッションがアクティブなままになる時間の長さを確立することが必須です。Webアプリケーションによるセッションの有効期限が不十分だと、他のセッションベースの攻撃にさらされる可能性が高くなります。攻撃者が有効なセッションIDを再利用して関連するセッションを乗っ取るには、そのセッションがまだアクティブである必要があります。

セッション間隔が短いほど、攻撃者が有効なセッションIDを使用できる時間が短くなります。セッション有効期限のタイムアウト値は、Webアプリケーションの目的と性質に応じて設定し、セキュリティと使いやすさのバランスをとる必要があります。そうすることで、ユーザーは頻繁にセッションが期限切れになることなく、Webアプリケーション内での操作を快適に完了できます。

アイドル タイムアウト値と絶対タイムアウト値はどちらも、Webアプリケーションとそのデータの重要度に大きく依存します。一般的なアイドル タイムアウト範囲は、高価値アプリケーションの場合は2 ~ 5分、低リスク アプリケーションの場合は15 ~ 30分です。絶対タイムアウトは、ユーザーが通常アプリケーションを使用する時間によって異なります。アプリケーションがオフィス ワーカーによって1日中使用されることを想定している場合、適切な絶対タイムアウト範囲は4 ~ 8時間になります。

セッションの有効期限が切れると、Webアプリケーションはクライアントとサーバーの両方でセッションを無効にするためのアクティブなアクションを実行する必要があります。セキュリティの観点からは、サーバー側が最も重要かつ必須です。

ほとんどのセッション交換メカニズムでは、セッションIDを無効にするクライアント側のアクションは、トークン値をクリアすることに基づいています。たとえば、Cookieを無効にするには、セッションIDに空 (または無効な) 値を指定し、Expires(またはMax-Age) 属性を過去の日付に設定することをお勧めします (永続的なCookieが使用されている場合)。Set-Cookie: id=; Expires=Friday, 17-May-03 18:45:00 GMT

サーバー側でセッションを閉じて無効にするには、セッションの有効期限が切れたとき、またはユーザーが積極的にログアウトしたときに、HttpSession.invalidate()(J2EE)、Session.Abandon()(ASP .NET)、session_destroy()/unset()(PHP) などのセッション管理メカニズムが提供する関数とメソッドを使用して、Webアプリケーションがアクティブなアクションを実行する必要があります。

自動セッション有効期限

アイドルタイムアウト

すべてのセッションは、アイドル タイムアウトまたは非アクティブ タイムアウトを実装する必要があります。このタイムアウトは、セッションにアクティビティがない場合にセッションがアクティブなままになる時間を定義します。指定されたセッションIDに対してWebアプリケーションが受信した最後のHTTP要求以降、定義されたアイドル期間が経過すると、セッションが閉じられ、無効になります。

アイドル タイムアウトにより、攻撃者が別のユーザーの有効なセッションIDを推測して使用する可能性が制限されます。ただし、攻撃者が特定のセッションをハイジャックできる場合、アイドル タイムアウトでは攻撃者のアクションが制限されず、攻撃者はセッションで定期的にアクティビティを生成して、セッションを長時間アクティブにしておくことができます。

セッション タイムアウトの管理と有効期限は、サーバー側で強制する必要があります。クライアントを使用してセッション タイムアウトを強制する場合 (たとえば、セッション トークンまたは他のクライアント パラメータを使用して時間参照 (ログイン時からの分数など) を追跡する)、攻撃者はこれらを操作してセッション期間を延長できます。

絶対タイムアウト

すべてのセッションは、セッション アクティビティに関係なく、絶対タイムアウトを実装する必要があります。このタイムアウトは、セッションがアクティブになることができる最大時間を定義します。セッションは、Webアプリケーションによって最初に作成されてから定義された絶対期間で閉じられ、無効になります。セッションが無効になった後、ユーザーはWebアプリケーションで再度認証 (再認証) され、新しいセッションを確立する必要があります。

絶対セッションは、攻撃者がハイジャックしたセッションを使用して被害者のユーザーになりすますことができる時間を制限します。

更新タイムアウト

あるいは、Webアプリケーションは追加の更新タイムアウトを実装できます。このタイムアウトの後、ユーザー セッションの途中で、セッション アクティビティ (したがってアイドル タイムアウト) とは関係なく、セッションIDが自動的に更新されます。

セッションが最初に作成されてから一定の時間が経過すると、Webアプリケーションはユーザー セッションの新しいIDを再生成し、クライアントでそのIDを設定または更新しようとします。以前のセッションID値は、クライアントが新しいIDを認識して使用を開始するまでの安全間隔を考慮して、しばらくの間は有効のままになります。その時点で、クライアントが現在のセッション内で新しいIDに切り替えると、アプリケーションは以前のIDを無効にします。

このシナリオでは、攻撃者が取得した可能性のある特定のセッションID値が、被害者のユーザー セッションがまだアクティブな場合でも、ユーザー セッションをハイジャックするために再利用される時間を最小限に抑えます。ユーザー セッションは、正当なクライアント上では存続し、開いたままですが、関連付けられたセッションID値は、更新タイムアウトが期限切れになるたびに、セッション期間中に定期的に透過的に更新されます。したがって、更新タイムアウトは、アイドル タイムアウトと絶対タイムアウトを補完します。特に、絶対タイムアウト値が時間の経過とともに大幅に延長される場合 (たとえば、ユーザー セッションを長時間開いたままにすることがアプリケーションの要件である場合) は、これが当てはまります。

実装によっては、更新タイムアウトが経過した直後に、以前のセッションIDがまだ有効な攻撃者が被害者のユーザーより先にリクエストを送信し、更新されたセッションIDの値を最初に取得するという競合状態が発生する可能性があります。少なくともこのシナリオでは、被害者のユーザーは、関連付けられたセッションIDが無効になったためにセッションが突然終了するため、攻撃に気付く可能性があります。

手動セッション有効期限

Webアプリケーションは、セキュリティを意識したユーザーがWebアプリケーションの使用を終了したら、セッションを積極的に閉じることができるメカニズムを提供する必要があります。

ログアウトボタン

Webアプリケーションは、ユーザーがいつでも手動でセッションを閉じることができるように、Webアプリケーションのヘッダーまたはメニューで使用可能で、すべてのWebアプリケーションのリソースとページからアクセスできる、目に見えて簡単にアクセスできるログアウト (ログオフ、終了、またはセッションを閉じる) ボタンを提供する必要があります。Session_Expirationセクションで説明されているように、 Webアプリケーションは少なくともサーバー側でセッションを無効にする必要があります。

注: 残念ながら、すべてのWebアプリケーションでユーザーが現在のセッションを閉じることができるわけではありません。そのため、クライアント側の拡張機能により、良心的なユーザーはセッションを慎重に閉じることでセッションを保護できます。

Web コンテンツのキャッシュ

セッションが終了した後でも、Webブラウザのキャッシュを通じて、セッション内で交換されたプライベートまたは機密データにアクセスできる可能性があります。したがって、Webアプリケーションは、HTTPおよびHTTPSを介して交換されるすべてのWebトラフィックに対して、制限的なキャッシュ ディレクティブを使用する必要があります。たとえば、Cache-ControlすべてPragmaのWebページまたは少なくとも機密性の高いWebページでは、HTTPヘッダーや同等のMETAタグを使用する必要があります。

Webアプリケーションによって定義されたキャッシュ ポリシーとは関係なく、Webアプリケーション コンテンツのキャッシュが許可されている場合、セッションIDはキャッシュされてはならないため、Cache-Control: no-cache="Set-Cookie, Set-Cookie2"WebクライアントがセッションID以外のすべてをキャッシュできるようにするには、ディレクティブを使用することを強くお勧めします (こちらを参照)。

セッション管理のための追加のクライアント側防御

Webアプリケーションは、クライアント側で追加の対策を講じることで、前述のセッション管理防御を補完できます。クライアント側の保護は、通常、JavaScriptのチェックと検証の形式で行われますが、完全な防御策ではなく、熟練した攻撃者によって簡単に破られる可能性がありますが、侵入者が回避しなければならない別の防御層を導入する可能性があります。

初回ログインタイムアウト

Webアプリケーションは、ログイン ページでJavaScriptコードを使用して、ページが読み込まれてセッションIDが付与されてからの時間を評価および測定できます。特定の時間が経過した後にログインを試行すると、クライアント コードは、ログインの最大時間が経過したことをユーザーに通知し、ログイン ページを再読み込みして新しいセッションIDを取得できます。

この追加の保護メカニズムは、セッションIDの事前認証の更新を強制し、セッション固定攻撃などで、以前に使用された (または手動で設定された) セッションIDが同じコンピューターを使用する次の被害者によって再利用されるシナリオを回避します。

Web ブラウザ ウィンドウを閉じるイベントでセッションを強制ログアウトする

Webアプリケーションは、JavaScriptコードを使用して、Webブラウザーのタブまたはウィンドウを閉じる (または戻る) イベントをすべてキャプチャし、Webブラウザーを閉じる前に現在のセッションを閉じるための適切なアクションを実行して、ユーザーがログアウト ボタンを使用して手動でセッションを閉じたことをエミュレートできます。

Webブラウザのクロスタブセッションを無効にする

ユーザーがログインしてセッションが確立されると、WebアプリケーションはJavaScriptコードを使用して、同じWebアプリケーションに対して新しいWebブラウザー タブまたはウィンドウが開かれた場合にユーザーに再認証を強制できます。Webアプリケーションは、複数のWebブラウザー タブまたはウィンドウが同じセッションを共有することを許可しません。そのため、アプリケーションはWebブラウザーがそれらのタブまたはウィンドウ間で同時に同じセッションIDを共有しないように強制しようとします。

注意: セッションIDがCookieを介して交換される場合、CookieはすべてのWebブラウザーのタブ/ウィンドウで共有されるため、このメカニズムは実装できません。

自動クライアントログアウト

JavaScriptコードは、Webアプリケーションのすべてのページ (または重要なページ) で使用して、アイドル タイムアウトの期限が切れた後に、ユーザーをログアウト ページ (前述のログアウト ボタンで使用されるのと同じリソース) にリダイレクトするなどして、クライアント セッションを自動的にログアウトできます。

サーバー側のアイドル タイムアウト機能をクライアント側のコードで強化する利点は、ユーザーが非アクティブ状態によってセッションが終了したことを確認できること、またはカウント ダウン タイマーと警告メッセージによってセッションの有効期限が近づいていることを事前に通知できることです。このユーザー フレンドリなアプローチにより、サーバー側で自動的に期限切れになったセッションが原因で大量の入力データを必要とするWebページで作業が失われるのを防ぐことができます。

セッション攻撃検出¶ セッションID推測とブルートフォース検出¶ 攻撃者が有効なセッションIDを推測またはブルート フォース攻撃しようとする場合、単一の (またはIPアドレス セット) から異なるセッションIDを使用して、ターゲットWebアプリケーションに対して複数の連続したリクエストを発行する必要があります。さらに、攻撃者がセッションIDの予測可能性を分析しようとする場合 (統計分析などを使用)、新しい有効なセッションIDを収集するために、単一の (またはIPアドレス セット) からターゲットWebアプリケーションに対して複数の連続したリクエストを発行する必要があります。

Webアプリケーションは、異なるセッションIDを収集 (または使用) する試行回数に基づいて両方のシナリオを検出し、問題のあるIPアドレスを警告および/またはブロックできる必要があります。

セッションIDの異常の検出

Webアプリケーションは、セッションIDの操作など、セッションIDに関連する異常の検出に重点を置く必要があります。OWASP AppSensorプロジェクトは、検出ポイントと応答アクションの形式で、異常と予期しない動作の検出に重点を置いた、Webアプリケーション内に組み込みの侵入検出機能を実装するためのフレームワークと方法論を提供します。外部の保護レイヤーを使用する代わりに、ビジネス ロジックの詳細と高度なインテリジェンスは、Webアプリケーションの内部からのみ利用できる場合があります。その場合、既存のCookieが変更または削除された場合、新しいCookieが追加された場合、別のユーザーのセッションIDが再利用された場合、またはセッションの途中でユーザーの場所またはユーザー エージェントが変更された場合など、複数のセッション関連の検出ポイントを確立できます。

セッションIDを他のユーザープロパティにバインドする¶ ユーザーの不正行為やセッション ハイジャックを検出 (および、場合によっては保護) することを目標として、セッションIDを他のユーザーまたはクライアント プロパティ (クライアントIPアドレス、User-Agent、クライアント ベースのデジタル証明書など) にバインドすることを強くお勧めします。Webアプリケーションが、確立されたセッションの途中でこれらのさまざまなプロパティ間で変更または異常を検出した場合、これはセッション操作やハイジャックの試みを示す非常に優れた指標であり、この単純な事実を使用して、疑わしいセッションを警告したり終了したりできます。

これらのプロパティは、Webアプリケーションがセッション攻撃を確実に防御するために使用することはできませんが、Webアプリケーションの検出 (および保護) 機能を大幅に向上させます。ただし、熟練した攻撃者は、同じネットワークを共有する (Wi-FiホットスポットなどのNAT環境では非常に一般的) か、同じ送信Webプロキシを使用する (企業環境では非常に一般的) ことで、被害者のユーザーに割り当てられた同じIPアドレスを再利用するか、またはUser-Agentを被害者のユーザーとまったく同じに見えるように手動で変更することで、これらの制御を回避できます。

セッションのライフサイクルのログ記録: セッションIDの作成、使用、破棄の監視¶ Webアプリケーションは、セッションのライフサイクル全体に関する情報を含めることで、ログ機能を強化する必要があります。特に、セッションIDの作成、更新、破棄などのセッション関連イベント、ログインおよびログアウト操作での使用の詳細、セッション内の権限レベルの変更、タイムアウトの有効期限、無効なセッション アクティビティ (検出された場合)、セッション中の重要なビジネス操作を記録することをお勧めします。

ログの詳細には、タイムスタンプ、ソースIPアドレス、要求された (およびセッション操作に関係する) Webターゲット リソース、HTTPヘッダー (User-AgentおよびRefererを含む)、GETおよびPOSTパラメーター、エラー コードとメッセージ、ユーザー名 (またはユーザー ID)、およびセッションID (Cookie、URL、GET、POSTなど) が含まれる場合があります。

セッションIDなどの機密データは、セッション ログをセッションIDのローカルまたはリモート開示や不正アクセスから保護するために、ログに含めないでください。ただし、ログ エントリを特定のセッションに関連付けるために、何らかのセッション固有の情報をログに記録する必要があります。セッションIDを公開せずにセッション固有のログ関連付けを可能にするために、セッションID自体ではなく、セッションIDのソルト ハッシュをログに記録することをお勧めします。

特に、Webアプリケーションは、現在アクティブなセッションをすべて管理できる管理インターフェースを徹底的に保護する必要があります。サポート担当者は、ユーザーになりすましてWebアプリケーションをユーザーと同じように操作し、セッション関連の問題や一般的な問題を解決するために、これらのインターフェースを使用することがよくあります。

セッション ログは、Webアプリケーション侵入検出の主要なデータ ソースの1つとなり、侵入防止システムによって、(1つまたは複数の) 攻撃が検出されたときに自動的にセッションを終了したり、ユーザー アカウントを無効にしたりするためにも使用されます。アクティブな保護が実装されている場合は、これらの防御アクションもログに記録する必要があります。

同時セッションログオン

同じユーザーによる複数の同時ログオンを、同じクライアントIPアドレスから許可するか、異なるクライアントIPアドレスから許可するかは、Webアプリケーションの設計上の決定事項です。Webアプリケーションで同時セッション ログオンを許可しない場合は、新しい認証イベントのたびに、以前に使用可能だったセッションを暗黙的に終了するか、アクティブのままにしておく必要があるセッションについてユーザーに問い合わせる (古いセッション、新しいセッション、または両方のセッションを通じて) など、効果的なアクションを実行する必要があります。

Webアプリケーションには、アクティブなセッションの詳細をいつでも確認したり、同時ログオンを監視してユーザーに警告したり、セッションを手動でリモートで終了するユーザー機能を提供したり、IPアドレス、ユーザー エージェント、ログイン日時、アイドル時間などの複数のクライアントの詳細を記録してアカウント アクティビティ履歴 (ログブック) を追跡したりできるユーザー機能を追加することをお勧めします。

セッション管理WAF保護

Webアプリケーションのソース コードが利用できない、または変更できない場合や、上記で詳述した複数のセキュリティ推奨事項とベスト プラクティスを実装するために必要な変更により、Webアプリケーション アーキテクチャの完全な再設計が必要になり、短期間で簡単に実装できない場合があります。

このようなシナリオでは、Webアプリケーションの防御を補完し、Webアプリケーションを可能な限り安全に保つという目標を掲げて、すでに説明したセッション管理の脅威を軽減できるWebアプリケーション ファイアウォール (WAF) などの外部保護を使用することをお勧めします。

Webアプリケーション ファイアウォールは、セッション ベースの攻撃に対する検出機能と保護機能を提供します。一方で、WAFでは、新しいCookieを設定するすべてのWebアプリケーション応答のヘッダーに基本的な書き換えルールを適用して、 や フラグSecureなどのCookieのセキュリティ属性の使用を強制することは簡単です。HttpOnlySet-Cookie

一方、より高度な機能を実装して、WAFがセッションと対応するセッションIDを追跡し、セッション固定 (権限の変更が検出されたときにクライアント側でセッションIDを更新することによって)、スティッキー セッションの強制 (セッションIDとIPアドレスやユーザー エージェントなどの他のクライアント プロパティとの関係を検証することによって)、またはセッション有効期限の管理 (クライアントとWebアプリケーションの両方にセッションの終了を強制することによって) に対するあらゆる種類の保護を適用できるようにすることもできます。

オープンソースのModSecurity WAFとOWASP Core Rule Setは、セキュリティCookie属性を検出して適用する機能、セッション固定攻撃に対する対策、スティッキー セッションを強制するセッション追跡機能を提供します。