CSRF 攻撃に対する保護
CSRF 攻撃から保護することができます。
手順
- web.xml ファイルを開きます。
- CSRF 攻撃から保護するために使用されるトークンを検証するには、アプリケーションで登録される要求バリデーターを作成します (web.xml ファイルにまだバリデーターが存在しない場合)。
例:
<context-param> <param-name>scui-request-validator-10</param-name> <param-value> com.sterlingcommerce.ui.web.platform.security.SCUICSRFTokenValidator </param-value> </context-param> - バリデーターが稼働できるモードを、以下のようにセットアップします。
- ALL - POST 要求と GET 要求の両方で、CSRF トークンが検証されます。
- POST (デフォルト) - GET 要求では、CSRF トークンは検証されません。 POST/PUT/UPDATE/DELETE 要求では、CSRF トークンが検証されます。
- NONE - バリデーターは、どの要求でも CSRF トークンを検証しません。
config.xml ファイルまたは web.xml ファイルのコンテキスト・パラメーターで、バリデーター・モードを指定できます (web.xml ファイルにまだバリデーター・モードが存在しない場合)。
モードが指定されていない場合、または検証モード用のコンテキスト・パラメーターが指定されていない場合、モードはデフォルトで POST になります。 IBM® では、要求の検証に POST モードを使用することをお勧めします。
例:
<context-param> <param-name>scui-csrf-validator-request-method</param-name> <param-value>POST</param-value> </context-param>注:- デフォルトでは、ほとんどのアプリケーションは、POST のみをバリデーター・モードとして使用するように構成されます。 したがって、GET 要求では CSRF トークンは検証されません。 POST/PUT/UPDATE/DELETE 要求では、CSRF トークンが検証されます。
- GET 要求は CSRF 保護されません。 そのため、機密性の高い動的アクション呼び出しでは、GET 要求を使用したり許可したりしないようにする必要があります。 代わりに、要求メソッドとして POST を使用できます。
- CSRF バリデーター・メソッドの構成を ALL に保持する場合、GET 要求の URL に CSRF トークンが公開されるリスクがあります。その結果、プロキシー・サーバーの各種の断続的な層やその他のネットワーク層のログに記録される可能性があります。
- URL 内の機密性の高い情報は、ユーザーのブラウザー、Web サーバー、2 つのエンドポイント間のフォワードまたはリバース・プロキシー・サーバーなど、さまざまな場所のログに記録される可能性があります。 また、URL は、ユーザーによって、画面上に表示されたり、ブックマークされたり、E メールで送信される可能性もあります。 これらは、オフサイト・リンクに接続されたときに、参照者のヘッダーを介してサード・パーティーに開示される可能性があります。 セッション・トークンまたは CSRF トークン (あるいは、その両方) を URL に含めると、攻撃に対する脆弱性が増します。
- CSRF 検証を使用する安全な方法は、POST 要求 (または PUT/DEL/UPDATE などの同等の要求) にのみ使用することです。 また、GET ではないため、CSRF トークンは常に POST パラメーターとして渡され、 URLの照会ストリングでは渡されません。 GET を含むすべて (ALL) のタイプの要求に対して CSRF 検証を有効にしたい場合は、
web.xmlで CSRF バリデーター・モード・パラメーターを変更して ALL に戻すことで、有効にできます。 しかしながら、これはお勧めできません。前述のように、CSRF トークンが URL に公開されるリスクが増し、それによってログに記録されるリスクが増すからです。 そのため、この構成を変更する場合は、その前に関連のリスクを適切に分析することが必要です。 scui-csrf-validator-request-methodが「ALL」に設定されている場合、CSRF トークンはログ内で入手可能になります。
- 必要な場合、以下のガイドラインを使用して、バリデーター用の URI (Universal Resource Indicator) 包含リストおよび除外リストをセットアップします。
- URI が除外リストにある場合、CSRF トークンの検証は行われません。
- URI が包含リストにあり、除外リストにはない場合、CSRF トークンの検証が行われます。
web.xml ファイル内の以下のコンテキスト・パラメーターを使用して、包含および除外のリストを作成します。 パラメーターはいくつでも指定できます。- csrf-include-uri
この値と同じ URI を持つ要求は、CSRF トークンの検証が行われます。
例 (web.xml の場合):
<context-param> <param-name>csrf.include.uri.endswith.stk.1</param-name> <param-value>.do</param-value> </context-param> - csrf-include-uri-endswith
この値で終了する URI を持つ要求は、CSRF トークンの検証が行われます。
例 (web.xml の場合):
<context-param> <param-name>csrf.include.uri.endswith.stk.2</param-name> <param-value>.xml</param-value> </context-param> - csrf-include-uri-regex
regex (パラメーターの値として指定) に一致する URI を持つ要求は、CSRF トークンの検証が行われます。
例 (web.xml の場合):
<context-param> <param-name>csrf.include.uri.stk.1</param-name> <param-value>/stk/home.jsp</param-value> </context-param> - csrf-bypass-uri
この値に一致する URI を持つ要求はバイパスされ、CSRF トークンは検査されません。
例 (web.xml の場合):
<context-param> <param-name>csrf.bypass.uri.stk.1</param-name> <param-value>/console/login.jsp</param-value> </context-param> - csrf-bypass-uri-endswith
この値で終了する URI を持つ要求は、バイパスされます。
例 (web.xml の場合):
<context-param> <param-name>csrf.bypass.uri.endswith.stk.1</param-name> <param-value>.js</param-value> </context-param> - csrf-bypass-uri-regex
regex (パラメーターの値として指定) に一致する URI を持つ要求は、CSRF トークンは検査されません。
例 (web.xml の場合):
<context-param> <param-name>csrf.bypass.uri.regex.stk.1</param-name> <param-value>[a-zA-Z0-0]*servlet/param-value> </context-param>
デフォルトでは、csrf-include パラメーターが指定されない場合でも、すべての URI が包含リストに含まれます。 URI が除外リストに存在することは、明示的に指定する必要があります。 包含リストが指定されていない場合、デフォルトでは、すべての URI が包含リストに含まれているものと見なされます。 すべての URI が CSRF トークンの検証対象になるのを避けるために、アプリケーションで特定の URI を包含リストに追加できます。
フレームワークでは、デフォルトで、gif、png、css、または js タイプのファイルを対象にした要求の CSRF 検証をバイパスするために除外リストを提供しています。
- ほとんどの CSRF 攻撃は、単に POST 要求をその同等の GET 要求に複製することによって機能します。 大抵のアプリケーションは POST 要求と GET 要求とを区別していないため、攻撃は通常機能します。 GET 要求と POST 要求とを区別するには、Struts アクションの定義で、アクションの requestMethodSupported パラメーターを使用して、バリデーターが稼働できるモードを以下のようにセットアップします。
- POST - (デフォルト) POST 要求のみ許可されます。
requestMethodSupported が設定されていないか、不明値である場合は、デフォルトで POST になります。
- ALL - GET 要求と POST 要求の両方が許可されます。
例:<action name="accountTransfer" class="com.AccountTransfer"> <param name="requestMethodSupported">POST</param> <param name="resourceId">AccountTransfer_Action002</param> </action>デフォルトでは、アプリケーション内のほとんどのアクションは、POST 要求のみを許可し、GET 要求は許可しないように構成されています。 ログイン、ログアウト、バージョン情報ページおよびランディング・ページの表示など、一部のアクションは、GET 要求も許可するように構成されます。 ただし、これらのアクションは機密性が高くなく、要求の一部としてバックエンドで変更/削除/更新の操作を行いません。 したがって、これらは CSRF に対して脆弱ではありません。
GET 要求を許可するように構成されている画面をカスタマイズする場合、マッシュアップ、API、ユーザー出口、またはサービスのいずれのバックエンドにも、その後続の層にも、変更/削除/更新の操作がないことを確認する必要があります。 そうでない場合、アクションは CSRF に対して脆弱です。 - POST - (デフォルト) POST 要求のみ許可されます。