5. 機能

Spring Security は、一般的な悪用に対する認証、認可、保護の包括的なサポートを提供します。また、他のライブラリとの統合を提供して、その使用箇所を簡素化します。

5.1 エクスプロイトに対する保護

Spring Security は、一般的な悪用に対する保護を提供します。可能な限り、保護はデフォルトで有効になっています。以下に、Spring Security が保護するさまざまなエクスプロイトの概要を示します。

5.1.1 クロスサイトリクエストフォージェリ (CSRF)

Spring は、クロスサイトリクエストフォージェリ (CSRF) (英語) 攻撃から保護するための包括的なサポートを提供します。以下のセクションでは、以下を検討します。

[Note] メモ

ドキュメントのこのパートでは、CSRF 保護の一般的なトピックについて説明します。サーブレットおよび WebFlux ベースのアプリケーションの CSRF 保護に関する特定の情報については、関連するセクションを参照してください。

CSRF 攻撃とは何ですか?

CSRF 攻撃を理解する最良の方法は、具体例を見ることです。

銀行の Web サイトが、現在ログインしているユーザーから別の銀行口座に送金できるフォームを提供していると仮定します。例: 転送フォームは次のようになります。

例 5.1: 転送フォーム

<form method="post"
    action="/transfer">
<input type="text"
    name="amount"/>
<input type="text"
    name="routingNumber"/>
<input type="text"
    name="account"/>
<input type="submit"
    value="Transfer"/>
</form>

対応する HTTP リクエストは次のようになります。

例 5.2: HTTP リクエストを転送する

POST /transfer HTTP/1.1
Host: bank.example.com
Cookie: JSESSIONID=randomid
Content-Type: application/x-www-form-urlencoded

amount=100.00&routingNumber=1234&account=9876

次に、銀行の Web サイトに認証したふりをして、ログアウトせずに悪の Web サイトにアクセスします。邪悪な Web サイトには、次の形式の HTML ページが含まれています。

例 5.3: 悪意のある転送フォーム

<form method="post"
    action="https://bank.example.com/transfer">
<input type="hidden"
    name="amount"
    value="100.00"/>
<input type="hidden"
    name="routingNumber"
    value="evilsRoutingNumber"/>
<input type="hidden"
    name="account"
    value="evilsAccountNumber"/>
<input type="submit"
    value="Win Money!"/>
</form>

お金を獲得したいため、送信ボタンをクリックします。このプロセスでは、意図せずに悪意のあるユーザーに 100 ドルを送金しました。これは、悪の Web サイトがあなたの Cookie を見ることができない一方で、銀行に関連付けられた Cookie がリクエストとともに送信されるためです。

最悪の場合、このプロセス全体が JavaScript を使用して自動化された可能性があります。つまり、ボタンをクリックする必要さえありませんでした。さらに、XSS 攻撃 (英語) の被害者である正直なサイトにアクセスすると、同じように簡単に発生する可能性があります。では、このような攻撃からユーザーをどのように保護するのでしょうか?

CSRF 攻撃からの保護

CSRF 攻撃が可能な理由は、被害者の Web サイトからの HTTP リクエストと攻撃者の Web サイトからのリクエストがまったく同じです。これは、悪の Web サイトからのリクエストを拒否し、銀行の Web サイトからのリクエストを許可する方法がないことを意味します。CSRF 攻撃から保護するために、2 つのリクエストを区別できるように、悪意のあるサイトが提供できないリクエストに何かがあることを確認する必要があります。

Spring は、CSRF 攻撃から保護するための 2 つのメカニズムを提供します。

[Note] メモ

両方の保護では、「安全なメソッドはべき等でなければならない」が必要です 。

安全なメソッドはべき等でなければなりません

CSRF に対するいずれかの保護が機能するためには、アプリケーションは「安全な」HTTP メソッドはべき等です (英語) を確認する必要があります。これは、HTTP メソッド  GET HEAD OPTIONS TRACE を使用したリクエストがアプリケーションの状態を変更してはならないことを意味します。

シンクロナイザートークンパターン

CSRF 攻撃から保護するための支配的で最も包括的な方法は、シンクロナイザートークンパターン (英語) を使用することです。この解決策は、セッション Cookie に加えて、各 HTTP リクエストで、CSRF トークンと呼ばれる安全なランダム生成値が HTTP リクエストに存在する必要があることを確認することです。

HTTP リクエストが送信されると、サーバーは予想される CSRF トークンを検索し、HTTP リクエストの実際の CSRF トークンと比較する必要があります。値が一致しない場合、HTTP リクエストは拒否されます。

この動作の鍵は、実際の CSRF トークンが、ブラウザーによって自動的に含まれない HTTP リクエストの一部にある必要があることです。例: HTTP パラメーターまたは HTTP ヘッダーに実際の CSRF トークンをリクエストすると、CSRF 攻撃から保護されます。Cookie はブラウザーによって HTTP リクエストに自動的に含まれるため、Cookie で実際の CSRF トークンをリクエストすることは機能しません。

アプリケーションの状態を更新する各 HTTP リクエストに対して実際の CSRF トークンのみをリクエストするように期待を緩和できます。それが機能するためには、アプリケーションは安全な HTTP メソッドがべき等であることを保証する必要があり ます。これにより、外部サイトからのリンクを使用して Web サイトへのリンクを許可するため、使いやすさが向上します。さらに、ランダムトークンを HTTP GET に含めないようにします。これにより、トークンがリークする可能性があります。

Synchronizer Token Pattern を使用した場合のがどのように変化するかを見てみましょう。実際の CSRF トークンが  _csrf という名前の HTTP パラメーターに含まれている必要があると仮定します。アプリケーションの転送フォームは次のようになります。

例 5.4: シンクロナイザートークンフォーム

<form method="post"
    action="/transfer">
<input type="hidden"
    name="_csrf"
    value="4bfd1575-3ad1-4d21-96c7-4ef2d9f86721"/>
<input type="text"
    name="amount"/>
<input type="text"
    name="routingNumber"/>
<input type="hidden"
    name="account"/>
<input type="submit"
    value="Transfer"/>
</form>

フォームには、CSRF トークンの値を持つ非表示の入力が含まれています。外部サイトは CSRF トークンを読み取ることができません。同じ発信元ポリシーにより、悪サイトはレスポンスを読み取れないためです。

送金に対応する HTTP リクエストは次のようになります。

例 5.5: シンクロナイザートークンリクエスト

POST /transfer HTTP/1.1
Host: bank.example.com
Cookie: JSESSIONID=randomid
Content-Type: application/x-www-form-urlencoded

amount=100.00&routingNumber=1234&account=9876&_csrf=4bfd1575-3ad1-4d21-96c7-4ef2d9f86721

HTTP リクエストに、安全なランダム値を持つ  _csrf パラメーターが含まれていることに気付くでしょう。悪の Web サイトは、 _csrf パラメーター(悪の Web サイトで明示的に提供する必要があります)に正しい値を提供できず、サーバーが実際の CSRF トークンと予想される CSRF トークンを比較すると、転送は失敗します。

SameSite 属性

CSRF 攻撃から保護する新しい方法は、Cookie で SameSite 属性 (英語) を指定することです。サーバーは、Cookie を設定するときに  SameSite 属性を指定して、外部サイトから来るときに Cookie を送信しないように指定できます。

[Note] メモ

Spring Security はセッション Cookie の作成を直接制御しないため、SameSite 属性のサポートは提供しません。 Spring Session は、サーブレットベースのアプリケーションで  SameSite 属性のサポートを提供します。Spring FrameworkCookieWebSessionIdResolver (Javadoc) は、WebFlux ベースのアプリケーションの  SameSite 属性をすぐにサポートします。

たとえば、 SameSite 属性を持つ HTTP レスポンスヘッダーは次のようになります。

例 5.6: SameSite HTTP レスポンス

Set-Cookie: JSESSIONID=randomid; Domain=bank.example.com; Secure; HttpOnly; SameSite=Lax

SameSite 属性の有効な値は次のとおりです。

  • Strict - 指定すると、同じサイト (英語) からのリクエストには Cookie が含まれます。それ以外の場合、Cookie は HTTP リクエストに含まれません。
  • Lax - 同じサイト (英語) から来るとき、またはトップレベルのナビゲーションからリクエストが来て、メソッドがべき等であるときに、指定されたクッキーが送信されるとき。それ以外の場合、Cookie は HTTP リクエストに含まれません。

SameSite 属性を使用してこの例を保護する方法を見てみましょう。銀行アプリケーションは、セッション Cookie で  SameSite 属性を指定することにより CSRF から保護できます。

セッション Cookie に  SameSite 属性が設定されていると、ブラウザーは、銀行の Web サイトからのリクエストとともに  JSESSIONID Cookie を送信し続けます。ただし、悪意のある Web サイトからの転送リクエストを含む  JSESSIONID Cookie はブラウザーから送信されなくなります。悪の Web サイトからの転送リクエストにはセッションが存在しないため、アプリケーションは CSRF 攻撃から保護されます。

SameSite 属性を使用して CSRF 攻撃から保護する場合に注意すべき重要な考慮事項 (英語) がいくつかあります。

SameSite 属性を  Strict に設定すると、強力な防御が提供されますが、ユーザーを混乱させる可能性があります。 https://social.example.com (英語) でホストされているソーシャルメディアサイトにログインしたままのユーザーを考えます。ユーザーは、https://email.example.org (英語) でソーシャルメディアサイトへのリンクを含むメールを受信します。ユーザーがリンクをクリックすると、ソーシャルメディアサイトへの認証が期待されます。ただし、 SameSite 属性が  Strict の場合、Cookie は送信されないため、ユーザーは認証されません。

[Note] メモ

gh-7537: GitHub (英語) を実装することにより、CSRF 攻撃に対する  SameSite 保護の保護と使いやすさを改善できます。

もう 1 つの明らかな考慮事項は、 SameSite 属性がユーザーを保護するために、ブラウザーが  SameSite 属性をサポートする必要があるということです。最新のブラウザーのほとんどは 、SameSite 属性をサポートしています 。ただし、まだ使用されている古いブラウザーはそうではない場合があります。

このため、CSRF 攻撃に対する唯一の保護ではなく、 SameSite 属性を徹底的な防御として使用することをお勧めします。

CSRF 保護を使用する場合

いつ CSRF 保護を使用する必要がありますか? 通常のユーザーがブラウザーで処理できるリクエストには CSRF 保護を使用することをお勧めします。ブラウザー以外のクライアントが使用するサービスのみを作成する場合は、CSRF 保護を無効にすることをお勧めします。

CSRF 保護と JSON

よくある質問は、「javascript によって作成された JSON リクエストを保護する必要がありますか? 」です。短い答えは、依存します。ただし、JSON リクエストに影響を与える可能性のある CSRF エクスプロイトがあるため、非常に注意する必要があります。例: 悪意のあるユーザーは次の形式を使用した JSON を使用した CSRF (英語) を作成できます:

例 5.7: JSON 形式の CSRF

<form action="https://bank.example.com/transfer" method="post" enctype="text/plain">
    <input name='{"amount":100,"routingNumber":"evilsRoutingNumber","account":"evilsAccountNumber", "ignore_me":"' value='test"}' type='hidden'>
    <input type="submit"
        value="Win Money!"/>
</form>

これにより、次の JSON 構造が生成されます

例 5.8: JSON リクエストを使用した CSRF

{ "amount": 100,
"routingNumber": "evilsRoutingNumber",
"account": "evilsAccountNumber",
"ignore_me": "=test"
}

アプリケーションが Content-Type を検証していない場合、このエクスプロイトにさらされます。セットアップに応じて、Content-Type を検証する Spring MVC アプリケーションは、以下に示すように  .json で終わるように URL サフィックスを更新することにより、依然として悪用される可能性があります。

例 5.9: JSON Spring MVC フォームを使用した CSRF

<form action="https://bank.example.com/transfer.json" method="post" enctype="text/plain">
    <input name='{"amount":100,"routingNumber":"evilsRoutingNumber","account":"evilsAccountNumber", "ignore_me":"' value='test"}' type='hidden'>
    <input type="submit"
        value="Win Money!"/>
</form>

CSRF およびステートレスブラウザーアプリケーション

アプリケーションがステートレスの場合はどうなるでしょうか? それは必ずしも保護されているという意味ではありません。実際、ユーザーが特定のリクエストに対して Web ブラウザーでアクションを実行する必要がない場合、ユーザーは CSRF 攻撃に対して依然として脆弱です。

例: JSESSIONID の代わりに、認証のためにすべての状態を含むカスタム Cookie を使用するアプリケーションを検討します。CSRF 攻撃が行われると、前の例で JSESSIONID Cookie が送信されたのと同じ方法で、リクエストとともにカスタム Cookie が送信されます。このアプリケーションは、CSRF 攻撃に対して脆弱です。

基本認証を使用するアプリケーションも CSRF 攻撃に対して脆弱です。前の例で JSESSIONID Cookie が送信されたのと同じ方法で、ブラウザーがリクエストにユーザー名とパスワードを自動的に含めるため、アプリケーションは脆弱です。

CSRF の考慮事項

CSRF 攻撃に対する保護を実装する際に考慮すべき特別な考慮事項がいくつかあります。

ログイン

ログインリクエスト (英語) 偽造 (英語) を防ぐには、HTTP リクエスト (英語) のログインを CSRF 攻撃から保護する必要があります。悪意のあるユーザーが被害者の機密情報を読み取れないように、ログインリクエストの偽造に対する保護が必要です。攻撃は次によって実行されます。

  • 悪意のあるユーザーは、悪意のあるユーザーの資格情報を使用して CSRF ログインを実行します。これで、被害者は悪意のあるユーザーとして認証されます。
  • 悪意のあるユーザーは、標的の Web サイトにアクセスして機密情報を入力するように被害者をだます
  • 情報は悪意のあるユーザーのアカウントに関連付けられているため、悪意のあるユーザーは自分の資格情報でログインし、被害者の機密情報を表示できます

ログイン HTTP リクエストが CSRF 攻撃から保護されるようにするための複雑な問題は、リクエストが拒否される原因となるセッションタイムアウトがユーザーに発生する可能性があることです。セッションタイムアウトは、ログインするためにセッションを必要としないユーザーにとっては驚くべきことです。詳細について は、「CSRF とセッションタイムアウト」を参照し てください。

ログアウト

ログアウトリクエストの偽造を防ぐには、ログアウト HTTP リクエストを CSRF 攻撃から保護する必要があります。悪意のあるユーザーが被害者の機密情報を読み取れないように、ログアウトリクエストの偽造に対する保護が必要です。攻撃の詳細については、このブログ投稿 (英語) を参照し てください。

ログアウト HTTP リクエストが CSRF 攻撃から保護されることを確実にするための複雑な問題は、リクエストが拒否される原因となるセッションタイムアウトが発生する可能性があることです。セッションタイムアウトは、ログアウトするためにセッションを持つ必要がないと考えているユーザーにとっては驚くべきことです。詳細について は、「CSRF およびセッションタイムアウト」を参照し てください。

CSRF およびセッションタイムアウト

多くの場合、予想される CSRF トークンはセッションに保存されます。これは、セッションが期限切れになるとすぐに、サーバーが期待される CSRF トークンを見つけられず、HTTP リクエストを拒否することを意味します。タイムアウトを解決するための多くのオプションがあり、それぞれにトレードオフがあります。

  • タイムアウトを軽減する最善の方法は、JavaScript を使用してフォーム送信時に CSRF トークンをリクエストすることです。その後、フォームは CSRF トークンで更新され、送信されます。
  • 別のオプションは、セッションが期限切れになることをユーザーに知らせる JavaScript を用意することです。ユーザーはボタンをクリックしてセッションを続行し、リフレッシュできます。
  • 最後に、期待される CSRF トークンを Cookie に保存できます。これにより、予想される CSRF トークンがセッションより長く存続できます。

    予想される CSRF トークンがデフォルトで Cookie に保存されない理由を確認するかもしれません。これは、ヘッダー(つまり、Cookie を指定)を別のドメインで設定できる既知のエクスプロイトがあるためです。これは、ヘッダー X-Requested-With が存在する場合 (英語) 、 Rails 上の Ruby が CSRF チェックをスキップしなくなっ (英語) たのと同じ理由です。エクスプロイトの実行メソッドの詳細については、この webappsec.org スレッド (英語) を参照してください。もう 1 つの欠点は、状態(タイムアウト)を削除すると、トークンが侵害された場合にトークンを強制的に終了する機能が失われることです。

マルチパート (ファイルアップロード)

CSRF 攻撃からマルチパートリクエスト(ファイルのアップロード)を保護すると、鶏と卵 (英語) の問題が発生します。CSRF 攻撃の発生を防ぐには、HTTP リクエストの本文を読み取って実際の CSRF トークンを取得する必要があります。ただし、本文を読むことは、ファイルがアップロードされることを意味し、外部サイトがファイルをアップロードできることを意味します。

multipart/form-data で CSRF 保護を使用するには、2 つのオプションがあります。各オプションにはトレードオフがあります。

[Note] メモ

Spring Security の CSRF 保護をマルチパートファイルアップロードと統合する前に、CSRF 保護なしでアップロードできることを確認してください。Spring でのマルチパートフォームの使用に関する詳細情報は、Spring リファレンスの 1.1.11. マルチパートリゾルバーセクションおよび MultipartFilter javadoc 内にあります。

CSRF トークンを本文に配置する

最初のオプションは、リクエストの本文に実際の CSRF トークンを含めることです。CSRF トークンを本文に配置すると、認可が実行される前に本文が読み取られます。これは、誰でもサーバーに一時ファイルを配置できることを意味します。ただし、認可されたユーザーのみが、アプリケーションで処理されるファイルを送信できます。一般に、これは推奨されるアプローチです。一時ファイルの更新はほとんどのサーバーにほとんど影響を与えないはずです。

URL に CSRF トークンを含める

認可されていないユーザーが一時ファイルをアップロードすることを認可しない場合は、フォームのアクション属性にクエリパラメーターとして予想される CSRF トークンを含めることもできます。このアプローチの欠点は、クエリパラメーターがリークする可能性があることです。より一般的には、機密データが漏れないように、本文またはヘッダー内に機密データを配置することをお勧めします。追加情報は URI の機密情報をエンコードする RFC 2616 セクション 15.1.3 (英語) にあります。

HiddenHttpMethodFilter

一部のアプリケーションでは、HTTP メソッドをオーバーライドするためにフォームパラメーターを使用できます。例: 以下の形式は、HTTP メソッドを  post ではなく  delete として扱うために使用できます。

例 5.10: CSRF 非表示 HTTP メソッドフォーム

<form action="/process"
    method="post">
    <!-- ... -->
    <input type="hidden"
        name="_method"
        value="delete"/>
</form>

HTTP メソッドのオーバーライドはフィルターで発生します。そのフィルターは、Spring Security のサポートの前に配置する必要があります。オーバーライドは  post でのみ発生するため、実際に問題が発生する可能性はほとんどありません。ただし、Spring Security のフィルターの前に配置することをお勧めします。

5.1.2 セキュリティ HTTP レスポンスヘッダー

[Note] メモ

ドキュメントのこのパートでは、セキュリティ HTTP レスポンスヘッダーの一般的なトピックについて説明します。Security HTTP Response Headers サーブレットおよび WebFlux ベースのアプリケーションに関する特定の情報については、関連するセクションを参照してください。

Web アプリケーションのセキュリティを強化するために使用できる多くの HTTP レスポンスヘッダー (英語) があります。このセクションは、Spring Security が明示的にサポートするさまざまな HTTP レスポンスヘッダー専用です。必要に応じて、Spring Security を構成してカスタムヘッダーを提供することもできます。

デフォルトのセキュリティヘッダー

[Note] メモ

関連セクションを参照して、サーブレットベースのアプリケーションと webflux ベースのアプリケーションの両方のデフォルトをカスタマイズする方法を確認してください。

Spring Security は、セキュリティ関連の HTTP レスポンスヘッダーのデフォルトセットを提供して、安全なデフォルトを提供します。

Spring Security のデフォルトでは、次のヘッダーが含まれます。

例 5.11: デフォルトのセキュリティ HTTP レスポンスヘッダー

Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block

[Note] メモ

Strict-Transport-Security は HTTPS リクエストでのみ追加されます

デフォルトがニーズを満たさない場合、これらのデフォルトからヘッダーを簡単に削除、変更、または追加できます。これらの各ヘッダーの詳細については、対応するセクションを参照してください。

キャッシュ制御

[Note] メモ

関連セクションを参照して、サーブレットベースのアプリケーションと webflux ベースのアプリケーションの両方のデフォルトをカスタマイズする方法を確認してください。

Spring Security のデフォルトでは、キャッシュを無効にしてユーザーのコンテンツを保護します。

ユーザーが機密情報を表示するために認証してからログアウトする場合、悪意のあるユーザーが戻るボタンをクリックして機密情報を表示できないようにする必要があります。デフォルトで送信されるキャッシュ制御ヘッダーは次のとおりです。

例 5.12: デフォルトのキャッシュ制御 HTTP レスポンスヘッダー

Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0

デフォルトでセキュアにするために、Spring Security はデフォルトでこれらのヘッダーを追加します。ただし、アプリケーションが独自のキャッシュ制御ヘッダーを提供する場合、Spring Security は邪魔になりません。これにより、アプリケーションは、CSS や JavaScript などの静的リソースを確実にキャッシュできます。

コンテンツタイプオプション

[Note] メモ

関連セクションを参照して、サーブレットベースのアプリケーションと webflux ベースのアプリケーションの両方のデフォルトをカスタマイズする方法を確認してください。

歴史的に、Internet Explorer を含むブラウザーは、コンテンツスニッフィング (英語) を使用してリクエストのコンテンツタイプを推測しようとしました。これにより、ブラウザーは、コンテンツタイプを指定していないリソースのコンテンツタイプを推測することで、ユーザーエクスペリエンスを向上させることができました。例: ブラウザーが、コンテンツタイプが指定されていない JavaScript ファイルを検出した場合、コンテンツタイプを推測して実行できます。

[Note] メモ

コンテンツのアップロードを許可する場合、行うべき追加事項が多数あります(つまり、ドキュメントを個別のドメインでのみ表示する、Content-Type ヘッダーが設定されていることを確認する、ドキュメントをサニタイズするなど)。ただし、これらの手段は Spring Security が提供するものの範囲外です。また、コンテンツスニッフィングを無効にする場合に指摘することも重要です。適切に機能するには、コンテンツタイプを指定する必要があります。

コンテンツスニッフィングの問題は、悪意のあるユーザーがポリグロット(つまり、複数のコンテンツタイプとして有効なファイル)を使用して XSS 攻撃を実行できることです。例: 一部のサイトでは、ユーザーが有効なポストスクリプトドキュメントを Web サイトに送信して表示できる場合があります。悪意のあるユーザーは 、有効な JavaScript ファイルでも (英語) あるポストスクリプトドキュメント (英語) を作成し、XSS 攻撃を実行する可能性があります。

Spring Security は、次のヘッダーを HTTP レスポンスに追加することにより、デフォルトでコンテンツスニッフィングを無効にします。

例 5.13: nosniff HTTP レスポンスヘッダー

X-Content-Type-Options: nosniff

HTTP Strict Transport Security (HSTS)

[Note] メモ

サーブレットwebflux ベースの両方のアプリケーションのデフォルトをカスタマイズする方法については、関連するセクションを参照してください。

銀行の Web サイトに入力するときに、mybank.example.com と入力しますか、それとも https://mybank.example.com (英語) と入力しますか? https プロトコルを省略すると、潜在的に中間者攻撃 (英語) に対して脆弱になります。Web サイトが https://mybank.example.com (英語) へのリダイレクトを実行した場合でも、悪意のあるユーザーは最初の HTTP リクエストをインターセプトしてレスポンスを操作できます(つまり、https://mibank.example.com (英語) にリダイレクトして資格情報を盗みます)。

多くのユーザーが https プロトコルを省略しているため、HTTP Strict Transport Security (HSTS) (英語) が作成されます。mybank.example.com が HSTS ホスト (英語) として追加されると、ブラウザーは mybank.example.com へのリクエストが https://mybank.example.com (英語) として解釈されるべきであることを事前に知ることができます。これにより、中間者攻撃が発生する可能性が大幅に減少します。

[Note] メモ

RFC6797 (英語) に従って、HSTS ヘッダーは HTTPS レスポンスにのみ挿入されます。ブラウザーがヘッダーを確認するには、ブラウザーは最初に、SSL 証明書だけでなく、接続に使用する SSL 証明書に署名した CA を信頼する必要があります。

サイトを HSTS ホストとしてマークする 1 つのメソッドは、ホストをブラウザーにプリロードすることです。もう 1 つのメソッドは、 Strict-Transport-Security ヘッダーをレスポンスに追加することです。例: Spring Security のデフォルトの動作は、ブラウザーにドメインを 1 年間 HSTS ホストとして扱うよう指示する次のヘッダーを追加することです(1 年で約 31536000 秒あります)。

例 5.14: Strict Transport Security HTTP レスポンスヘッダー

Strict-Transport-Security: max-age=31536000 ; includeSubDomains ; preload

オプションの  includeSubDomains ディレクティブは、サブドメイン(つまり、secure.mybank.example.com)も HSTS ドメインとして扱う必要があることをブラウザーに指示します。

オプションの  preload ディレクティブは、ブラウザーに HSTS ドメインとしてドメインをプリロードするよう指示します。HSTS プリロードの詳細については、https://hstspreload.org (英語) を参照してください。

HTTP 公開鍵ピンニング (HPKP)

[Note] メモ

パッシブを維持する ために、Spring Security はサーブレット環境HPKP をサポートしていますが、上記の理由により、HPKP はセキュリティチームによって推奨されなくなりました。

HTTP 公開鍵ピンニング (HPKP) は、偽造された証明書による中間者(MITM)攻撃を防ぐために特定の Web サーバーで使用する公開鍵を Web クライアントに指定します。HPKP を正しく使用すると、侵害された証明書に対する保護層を追加できます。ただし、HPKP は複雑であるため、多くの専門家は HPKP の使用を推奨しなくなり、Chrome はサポートを削除しました (英語)

HPKP が推奨されなくなった理由の詳細については、 HTTP 公開鍵ピンニングは無効ですか? (英語) および HPKP をあきらめています (英語) を参照してください。

X-Frame-Options

[Note] メモ

関連セクションを参照して、サーブレットベースのアプリケーションと webflux ベースのアプリケーションの両方のデフォルトをカスタマイズする方法を確認してください。

Web サイトをフレームに追加できるようにすることは、セキュリティ上の課題になる可能性があります。例: 賢い CSS スタイリングを使用すると、ユーザーはだまされて意図しないものをクリックする可能性があります(ビデオデモ (英語) )。例: 銀行にログインしているユーザーは、他のユーザーにアクセスを許可するボタンをクリックする場合があります。この種の攻撃はクリックジャッキング (英語) として知られています。

[Note] メモ

クリックジャッキングに対処する別の現代的なアプローチは、「コンテンツセキュリティポリシー(CSP)」を使用することです。

クリックジャック攻撃を緩和する方法はいくつかあります。例: クリックジャッキング (英語) 攻撃からレガシーブラウザーを保護するために、フレーム破壊コード (英語) を使用できます。完璧ではありませんが、フレーム破壊コードはレガシーブラウザーでできる最善の方法です。

クリックジャックに対処するためのより現代的なアプローチは、X-Frame-Options ヘッダーを使用することです。デフォルトでは、Spring Security は次のヘッダーを使用して iframe 内のページのレンダリングを無効にします。

X-Frame-Options: DENY

X-XSS-Protection

[Note] メモ

関連セクションを参照して、サーブレットベースのアプリケーションと webflux ベースのアプリケーションの両方のデフォルトをカスタマイズする方法を確認してください。

一部のブラウザーには、リフレクションされた XSS 攻撃 (英語) を除外するためのサポートが組み込まれています。これは決して絶対確実ではありませんが、XSS 保護を支援します。

通常、フィルタリングはデフォルトで有効になっているため、ヘッダーを追加すると、通常は有効になり、XSS 攻撃が検出されたときにブラウザーに何をするかが指示されます。例: フィルターは、コンテンツを最も侵襲性の低い方法で変更して、すべてをレンダリングしようとする場合があります。時々、このタイプの交換は XSS 自体の脆弱性 (英語) になることがあります。代わりに、コンテンツを修正するのではなく、ブロックすることをお勧めします。デフォルトでは、Spring Security は次のヘッダーを使用してコンテンツをブロックします。

X-XSS-Protection: 1; mode=block

コンテンツセキュリティポリシー (CSP)

[Note] メモ

関連するセクションを参照して、サーブレットベースのアプリケーションと webflux ベースのアプリケーションの両方を設定する方法を確認してください。

コンテンツセキュリティポリシー (CSP) (英語) は、クロスサイトスクリプティング(XSS)などのコンテンツインジェクションの脆弱性を軽減するために Web アプリケーションが活用できるメカニズムです。CSP は、Web アプリケーションの作成者が Web アプリケーションがリソースをロードすることを期待しているソースを宣言し、最終的にクライアント(ユーザーエージェント)に通知する機能を提供する宣言型ポリシーです。

[Note] メモ

コンテンツセキュリティポリシーは、すべてのコンテンツインジェクションの脆弱性を解決するためのものではありません。代わりに、CSP を活用して、コンテンツインジェクション攻撃による被害を軽減することができます。防衛の最前線として、Web アプリケーションの作成者は入力を検証し、出力をエンコードする必要があります。

Web アプリケーションは、次の HTTP ヘッダーのいずれかをレスポンスに含めることにより、CSP の使用を採用できます。

  • Content-Security-Policy
  • Content-Security-Policy-Report-Only

これらの各ヘッダーは、セキュリティポリシーをクライアントに配信するメカニズムとして使用されます。セキュリティポリシーには、特定のリソース表現の制限を宣言するセキュリティポリシーディレクティブのセットが含まれています。

例: Web アプリケーションは、レスポンスに次のヘッダーを含めることにより、特定の信頼できるソースからスクリプトを読み込むことを宣言できます。

例 5.15: コンテンツセキュリティポリシーの例

Content-Security-Policy: script-src https://trustedscripts.example.com

script-src ディレクティブで宣言されているもの以外の別のソースからスクリプトをロードしようとすると、ユーザーエージェントによってブロックされます。さらに、 report-uri (英語) ディレクティブがセキュリティポリシーで宣言されている場合、ユーザーエージェントによって、宣言された URL に違反が報告されます。

例: Web アプリケーションが宣言されたセキュリティポリシーに違反する場合、次のレスポンスヘッダーは、ポリシーの  report-uri ディレクティブで指定された URL に違反レポートを送信するようユーザーエージェントに指示します。

例 5.16: report-uri を使用したコンテンツセキュリティポリシー

Content-Security-Policy: script-src https://trustedscripts.example.com; report-uri /csp-report-endpoint/

違反レポート (英語) は、Web アプリケーションの独自の API または https://report-uri.io/ (英語) などのパブリックにホストされた CSP 違反レポートサービスのいずれかによってキャプチャーできる標準の JSON 構造です。

Content-Security-Policy-Report-Only ヘッダーは、Web アプリケーションの作成者および管理者がセキュリティポリシーを実施するのではなく、監視する機能を提供します。通常、このヘッダーは、サイトのセキュリティポリシーを実験および / または開発するときに使用されます。ポリシーが有効であると見なされる場合、代わりに  Content-Security-Policy ヘッダーフィールドを使用してポリシーを施行できます。

次のレスポンスヘッダーを指定すると、ポリシーは、2 つの可能なソースのいずれかからスクリプトをロードできることを宣言します。

例 5.17: コンテンツセキュリティポリシーレポートのみ

Content-Security-Policy-Report-Only: script-src 'self' https://trustedscripts.example.com; report-uri /csp-report-endpoint/

サイトがこのポリシーに違反している場合、 evil.com からスクリプトをロードしようとすると、ユーザーエージェントは、 report-uri ディレクティブで指定された宣言された URL に違反レポートを送信しますが、それでも違反リソースはロードできます。

Web アプリケーションへのコンテンツセキュリティポリシーの適用は、多くの場合、重要な作業です。次のリソースは、サイトの効果的なセキュリティポリシーを開発する際にさらに役立つ場合があります。

コンテンツセキュリティポリシーの概要 (英語)

CSP ガイド - Mozilla Developer Network

W3C 候補勧告 (英語)

リファラーポリシー

[Note] メモ

関連するセクションを参照して、サーブレットベースのアプリケーションと webflux ベースのアプリケーションの両方を設定する方法を確認してください。

リファラーポリシー (英語) は、Web アプリケーションがリファラーフィールドを管理するために活用できるメカニズムです。リファラーフィールドには、ユーザーが最後にアクセスしたページが含まれます。

Spring Security のアプローチは、異なるポリシー (英語) を提供するリファラーポリシー (英語) ヘッダーを使用することです。

例 5.18: リファラーポリシーの例

Referrer-Policy: same-origin

Referrer-Policy レスポンスヘッダーは、ユーザーが以前いたソースを宛先に知らせるようにブラウザーに指示します。

機能ポリシー

[Note] メモ

関連するセクションを参照して、サーブレットベースのアプリケーションと webflux ベースのアプリケーションの両方を設定する方法を確認してください。

機能ポリシー (英語) は、Web 開発者がブラウザーの特定の API および Web 機能の動作を選択的に有効化、無効化、変更できるようにするメカニズムです。

例 5.19: 機能ポリシーの例

Feature-Policy: geolocation 'self'

機能ポリシーを使用すると、開発者はブラウザーの一連の「ポリシー」をオプトインして、サイト全体で使用される特定の機能に適用できます。これらのポリシーは、サイトがアクセスできる API を制限したり、特定の機能に対するブラウザーのデフォルトの動作を変更したりします。

サイトデータを消去する

[Note] メモ

関連するセクションを参照して、サーブレットベースのアプリケーションと webflux ベースのアプリケーションの両方を設定する方法を確認してください。

サイトデータを消去する (英語) は、HTTP レスポンスに次のヘッダーが含まれている場合に、ブラウザー側のデータ(Cookie、ローカルストレージなど)を削除できるメカニズムです。

Clear-Site-Data: "cache", "cookies", "storage", "executionContexts"

これは、ログアウト時に実行するクリーンアップアクションです。

カスタムヘッダー

[Note] メモ

関連するセクションを参照して、両方のサーブレットベースのアプリケーションを構成する方法を確認してください。

Spring Security には、より一般的なセキュリティヘッダーをアプリケーションに追加するのに便利なメカニズムがあります。ただし、カスタムヘッダーの追加を可能にするフックも提供します。

5.1.3 HTTP

静的リソース (英語) を含むすべての HTTP ベースの通信は、 TLS を使用して (英語) 保護 する (英語) 必要があり ます。

フレームワークとして、Spring Security は HTTP 接続を処理しないため、HTTPS を直接サポートしません。ただし、HTTPS の使用に役立つ多くの機能を提供します。

HTTPS にリダイレクト

クライアントが HTTP を使用する場合、Spring Security は、サーブレット環境と WebFlux 環境の両方を HTTPS にリダイレクトするように構成できます。

Strict Transport Security

Spring Security は Strict Transport Security をサポートし、デフォルトで有効にします。

プロキシサーバー構成

プロキシサーバーを使用する場合は、アプリケーションが正しく構成されていることを確認することが重要です。例: 多くのアプリケーションには、https://example.com/ (英語) のリクエストに応答するロードバランサがあり、https://192.168.1:8080 (英語) のアプリケーションサーバーにリクエストを転送します。適切に構成しないと、アプリケーションサーバーはロードバランサが存在することを認識せず、クライアントから https://192.168.1:8080 (英語) がリクエストされたかのようにリクエストを処理します。

これを修正するには、RFC 7239 (英語) を使用して、ロードバランサーが使用されていることを指定します。アプリケーションがこれを認識できるようにするには、X-Forwarded ヘッダーを認識するようにアプリケーションサーバーを構成する必要があります。たとえば、Tomcat は RemoteIpValve: Apache (英語) を使用し、Jetty は ForwardedRequestCustomizer (英語) を使用します。または、Spring ユーザーは ForwardedHeaderFilter: GitHub (英語) を活用できます。

Spring Boot ユーザーは、 server.use-forward-headers プロパティを使用してアプリケーションを構成できます。詳細については、Spring Boot のドキュメントを参照してください。

現行バージョンへ切り替える