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

14.1 サーブレット環境のクロスサイトリクエストフォージェリ(CSRF)

このセクションでは、サーブレット環境に対する Spring Securityクロスサイトリクエストフォージェリ (CSRF) サポートについて説明します。

14.1.1 Spring Security CSRF 保護の使用

Spring Security の CSRF 保護を使用する手順の概要は次のとおりです。

適切な HTTP 動詞を使用する

CSRF 攻撃から保護するための最初のステップは、Web サイトが適切な HTTP 動詞を使用するようにすることです。これについては、安全なメソッドはべき等でなければなりませんで詳しく説明しています。

CSRF 保護を構成する

次のステップは、Spring Security の CSRF 保護をアプリケーション内で構成することです。Spring Security の CSRF 保護はデフォルトで有効になっていますが、構成をカスタマイズする必要がある場合があります。以下は、いくつかの一般的なカスタマイズです。

カスタム CsrfTokenRepository

デフォルトでは、Spring Security は、 HttpSessionCsrfTokenRepository を使用して、期待される CSRF トークンを  HttpSession に保存します。ユーザーがカスタム  CsrfTokenRepository を構成したい場合があります。例: JavaScript ベースのアプリケーションサポートするために、CsrfToken  を Cookie に保持することが望ましい場合があり ます 。

デフォルトでは、 CookieCsrfTokenRepository は  XSRF-TOKEN という名前の Cookie に書き込み、 X-XSRF-TOKEN という名前のヘッダーまたは HTTP パラメーター  _csrf からそれを読み取ります。これらのデフォルトは AngularJS (英語) からのものです

以下を使用して、 CookieCsrfTokenRepository を XML で構成できます。

例 14.1: XML 設定で Cookie に CSRF トークンを保存する

<http>
    <!-- ... -->
    <csrf token-repository-ref="tokenRepository"/>
</http>
<b:bean id="tokenRepository"
    class="org.springframework.security.web.csrf.CookieCsrfTokenRepository"
    p:cookieHttpOnly="false"/>

[Note] メモ

サンプルは  cookieHttpOnly=false を明示的に設定します。これは、JavaScript(つまり、AngularJS)が読み取れるようにするために必要です。JavaScript で Cookie を直接読み取る機能が必要ない場合は、 cookieHttpOnly=false を省略してセキュリティを向上させることをお勧めします。

以下を使用して、Java 構成で  CookieCsrfTokenRepository を構成できます。

例 14.2: Java 構成で Cookie に CSRF トークンを保存する

@EnableWebSecurity
public class WebSecurityConfig extends
        WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) {
        http
            .csrf(csrf ->
                csrf
                    .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
            );
    }
}

[Note] メモ

サンプルは  cookieHttpOnly=false を明示的に設定します。これは、JavaScript(つまり、AngularJS)が読み取れるようにするために必要です。JavaScript で Cookie を直接読み取る機能が必要ない場合は、 cookieHttpOnly=false を省略して(代わりに  new CookieCsrfTokenRepository() を使用して)セキュリティを向上させることをお勧めします。

CSRF 保護を無効にする

CSRF 保護はデフォルトで有効になっています。ただし、アプリケーションにとって意味がある場合、CSRF 保護を無効にするのは簡単 です 。

以下の XML 構成は、CSRF 保護を無効にします。

例 14.3: CSRF XML 設定を無効にする

<http>
    <!-- ... -->
    <csrf disabled="true"/>
</http>

以下の Java 構成は、CSRF 保護を無効にします。

例 14.4: CSRF Java 構成を無効にする

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends
        WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) {
        http
            .csrf(csrf ->
                csrf.disable()
            );
    }
}

CSRF トークンを含める

シンクロナイザートークンパターンを CSRF 攻撃から保護するには、実際の CSRF トークンを HTTP リクエストに含める必要があります。これは、ブラウザーによって HTTP リクエストに自動的に含まれないリクエストの一部(フォームパラメーター、HTTP ヘッダーなど)に含まれる必要があります。

Spring Security の CsrfFilter (Javadoc) は、CsrfToken (Javadoc) を  _csrf という名前の  HttpServletRequest 属性として公開します。これは、任意のビューテクノロジが  CsrfToken にアクセスして、期待されるトークンをフォームまたはメタタグとして公開できることを意味します。幸いなことに、トークンをフォームおよび ajax リクエストにさらに簡単に含めることができる統合が以下にリストされています。

エンコードされたフォーム URL

HTML フォームを送信するには、CSRF トークンを非表示の入力としてフォームに含める必要があります。例: レンダリングされた HTML は次のようになります。

例 14.5: CSRF トークン HTML

<input type="hidden"
    name="_csrf"
    value="4bfd1575-3ad1-4d21-96c7-4ef2d9f86721"/>

次に、CSRF トークンを非表示入力としてフォームに含めるさまざまな方法について説明します。

自動 CSRF トークンの包含

Spring Security の CSRF サポートは、CsrfRequestDataValueProcessor (Javadoc) を介して Spring の RequestDataValueProcessor (Javadoc) との統合を提供します。これは、Spring のフォームタグライブラリシンリーフ (英語) 、または  RequestDataValueProcessor と統合する他のビューテクノロジーを活用する場合、安全でない HTTP メソッド(つまり、投稿)を持つフォームには実際の CSRF トークンが自動的に含まれることを意味します。

csrfInput タグ

JSP を使用している場合は、Spring のフォームタグライブラリを使用できます。ただし、それがオプションでない場合は、 csrfInput タグでトークンを簡単に含めることもできます。

CsrfToken リクエスト属性

リクエストに実際の CSRF トークンを含めるための他のオプションが機能しない場合、 CsrfToken が _csrf という名前の  HttpServletRequest 属性として公開さ れているという事実を利用できます。

JSP でこれを実行する例を以下に示します。

例 14.6: リクエスト属性を持つフォームの CSRF トークン

<c:url var="logoutUrl" value="/logout"/>
<form action="${logoutUrl}"
    method="post">
<input type="submit"
    value="Log out" />
<input type="hidden"
    name="${_csrf.parameterName}"
    value="${_csrf.token}"/>
</form>

Ajax および JSON リクエスト

JSON を使用している場合、HTTP パラメーター内で CSRF トークンを送信することはできません。代わりに、HTTP ヘッダー内でトークンを送信できます。

次のセクションでは、JavaScript ベースのアプリケーションで CSRF トークンを HTTP リクエストヘッダーとして含めるさまざまな方法について説明します。

自動包含

Spring Security は、予想される CSRF トークンを Cookie に保存する よう に簡単に構成できます。期待される CSRF を Cookie に保存することにより、AngularJS (英語) などの JavaScript フレームワークは、実際の CSRF トークンを HTTP リクエストヘッダーに自動的に含めます。

メタタグ

Cookie で CSRF公開する別のパターンは、 meta タグ内に CSRF トークンを含めることです。HTML は次のようになります。

例 14.7: CSRF メタタグ HTML

<html>
<head>
    <meta name="_csrf" content="4bfd1575-3ad1-4d21-96c7-4ef2d9f86721"/>
    <meta name="_csrf_header" content="X-CSRF-TOKEN"/>
    <!-- ... -->
</head>
<!-- ... -->

メタタグに CSRF トークンが含まれると、JavaScript コードはメタタグを読み取り、CSRF トークンをヘッダーとして含めます。jQuery を使用している場合、これは次の方法で実行できます。

例 14.8: AJAX 送信 CSRF トークン

$(function () {
    var token = $("meta[name='_csrf']").attr("content");
    var header = $("meta[name='_csrf_header']").attr("content");
    $(document).ajaxSend(function(e, xhr, options) {
        xhr.setRequestHeader(header, token);
    });
});

csrfMeta タグ

JSP を使用している場合、CSRP トークンを  meta タグに書き込む簡単な方法は、csrfMeta タグを利用すること です 。

CsrfToken リクエスト属性

リクエストに実際の CSRF トークンを含めるための他のオプションが機能しない場合、 CsrfToken が _csrf という名前の  HttpServletRequest 属性として公開さ れているという事実を利用できます。JSP でこれを実行する例を以下に示します。

例 14.9: CSRF メタタグ JSP

<html>
<head>
    <meta name="_csrf" content="${_csrf.token}"/>
    <!-- default header name is X-CSRF-TOKEN -->
    <meta name="_csrf_header" content="${_csrf.headerName}"/>
    <!-- ... -->
</head>
<!-- ... -->

14.1.2 CSRF の考慮事項

CSRF 攻撃に対する保護を実装する際に考慮すべき特別な考慮事項がいくつかあります。このセクションでは、サーブレット環境に関連する考慮事項について説明します。より一般的な説明については、「CSRF に関する考慮事項」と呼ばれるセクションを 参照し て ください。

ログイン

ログインリクエストの偽造を防ぐために 、ログインリクエストに CSRFリクエストすることが重要 です 。Spring Security のサーブレットサポートは、これをすぐに実行できます。

ログアウト

ログアウト試行の偽造を防ぐために 、ログアウトリクエストに CSRFリクエストすることが重要 です 。CSRF 保護が有効になっている場合(デフォルト)、Spring Security の  LogoutFilter は HTTP POST のみを処理します。これにより、ログアウトに CSRF トークンが必要になり、悪意のあるユーザーがユーザーを強制的にログアウトできなくなります。

最も簡単な方法は、フォームを使用してログアウトすることです。本当にリンクが必要な場合は、JavaScript を使用して、リンクに POST を実行させることができます(つまり、非表示のフォームで)。JavaScript が無効になっているブラウザーの場合、オプションで、POST を実行するログアウト確認ページにユーザーをリンクさせることができます。

本当にログアウトで HTTP GET を使用したい場合は使用できますが、これは一般的に推奨されないことを忘れないでください。例: 次の Java 構成は、任意の HTTP メソッドで  /logout がリクエストされた URL でログアウトを実行します。

例 14.10: HTTP GET でログアウトする

@EnableWebSecurity
public class WebSecurityConfig extends
        WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) {
        http
            .logout(logout ->
                logout
                    .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
            );
    }
}

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

デフォルトでは、Spring Security は CSRF トークンを  HttpSession に保存します。これにより、セッションの有効期限が切れる状況が発生する可能性があります。つまり、検証対象の CSRF トークンが存在しないことがあります。

セッションタイムアウトの一般的なソリューションについてはすでに説明しました。このセクションでは、サーブレットサポートに関連する CSRF タイムアウトの詳細について説明します。

予想される CSRF トークンのストレージを Cookie に変更するのは簡単です。詳細については、「カスタム CsrfTokenRepository」セクション と呼ばれるセクションを 参照してください。

トークンの有効期限が切れた場合、カスタム  AccessDeniedHandler を指定して、トークンの処理方法をカスタマイズできます。カスタム  AccessDeniedHandler は、 InvalidCsrfTokenException を任意の方法で処理できます。 AccessDeniedHandler をカスタマイズする方法の例については、 xmlJava 構成: GitHub (英語) の両方について提供されているリンクを参照してください。

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

CSRF 攻撃からマルチパートリクエスト(ファイルのアップロード)を保護すると、鶏と卵 (英語) の 問題がどのように発生するか について はすでに説明しました。このセクションでは、サーブレットアプリケーション内で CSRF トークンを本文URL に 配置する方法を説明します。

[Note] メモ

Spring でマルチパートフォームを使用する方法の詳細については、Spring リファレンスの 1.1.11. マルチパートリゾルバーセクションおよび MultipartFilter javadoc を参照してください。

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

CSRF トークンを本文に配置することのトレードオフ について はすでに説明しました。このセクションでは、本体から CSRF を読み取るように Spring Security を構成する方法について説明します。

本体から CSRF トークンを読み取るために、 MultipartFilter は Spring Security フィルターの前に指定されます。Spring Security フィルターの前に  MultipartFilter を指定すると、 MultipartFilter を呼び出す権限がないため、だれでもサーバーに一時ファイルを配置できます。ただし、認可されたユーザーのみが、アプリケーションで処理されるファイルを送信できます。一般的に、一時ファイルのアップロードはほとんどのサーバーにほとんど影響を与えないはずなので、これが推奨されるアプローチです。

java 構成の Spring Security フィルターの前に  MultipartFilter が指定されるようにするために、ユーザーは、次に示すように beforeSpringSecurityFilterChain をオーバーライドできます。

例 14.11: イニシャライザー MultipartFilter

public class SecurityApplicationInitializer extends AbstractSecurityWebApplicationInitializer {

    @Override
    protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
        insertFilters(servletContext, new MultipartFilter());
    }
}

XML 構成の Spring Security フィルターの前に  MultipartFilter を指定するために、ユーザーは、以下に示すように、web.xml 内の springSecurityFilterChain の前に  MultipartFilter の <filter-mapping> エレメントを配置することができます。

例 14.12: web.xml - MultipartFilter

<filter>
    <filter-name>MultipartFilter</filter-name>
    <filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
</filter>
<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>MultipartFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

URL に CSRF トークンを含める

認可されていないユーザーによる一時ファイルのアップロードを認可しない場合は、Spring Security フィルターの後に  MultipartFilter を配置し、フォームのアクション属性にクエリパラメーターとして CSRF を含めることもできます。 CsrfToken は  HttpServletRequest  リクエスト属性として公開されているため、それを使用して CSRF トークンを含む  action を作成できます。jsp を使用した例を以下に示します

例 14.13: 実行中の CSRF トークン

<form method="post"
    action="./upload?${_csrf.parameterName}=${_csrf.token}"
    enctype="multipart/form-data">

HiddenHttpMethodFilter

CSRF トークンを本文に配置することのトレードオフ について はすでに説明しました。

Spring のサーブレットサポートでは、HiddenHttpMethodFilter (Javadoc) を使用して HTTP メソッドをオーバーライドします。詳細については、リファレンスドキュメントの HTTP メソッド変換セクションを参照してください。

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

セキュリティ HTTP レスポンスヘッダーを使用して、Web アプリケーションのセキュリティを強化できます。このセクションは、セキュリティ HTTP レスポンスヘッダーのサーブレットベースのサポートに特化しています。

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

Spring Security は、セキュリティ HTTP レスポンスヘッダーのデフォルトセットを提供して、安全なデフォルトを提供します。これらのヘッダーはそれぞれベストプラクティスと見なされますが、すべてのクライアントがヘッダーを使用するわけではないため、追加のテストが推奨されます。

特定のヘッダーをカスタマイズできます。例: X-Frame-Options に  SAMEORIGIN を指定する場合を除き、デフォルトが必要であると想定します。

これは、次の Java 構成を使用して簡単に実行できます。

例 14.14: Java 構成でデフォルトのセキュリティヘッダーをカスタマイズする

@EnableWebSecurity
public class WebSecurityConfig extends
        WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) {
        http
            // ...
            .headers(headers ->
                headers
                    .frameOptions(frameOptions ->
                        frameOptions.sameOrigin()
                    )
            );
    }
}

または、Spring Security XML 構成を使用している場合は、次を使用できます。

例 14.15: XML 設定でデフォルトのセキュリティヘッダーをカスタマイズする

<http>
    <!-- ... -->

    <headers>
        <frame-options policy="SAMEORIGIN" />
    </headers>
</http>

デフォルトの追加を望まず、使用するものを明示的に制御したい場合は、デフォルトを無効にできます。Java および XML ベースの構成の例を以下に示します。

Spring Security の Java 構成を使用している場合、以下はキャッシュ制御のみを追加します。

@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            // ...
            .headers(headers ->
                headers
                    // do not use any default headers unless explicitly listed
                    .defaultsDisabled()
                    .cacheControl(withDefaults())
            );
    }
}

次の XML はキャッシュ制御のみを追加します。

<http>
    <!-- ... -->

    <headers defaults-disabled="true">
        <cache-control/>
    </headers>
</http>

必要に応じて、次の Java 構成ですべての HTTP セキュリティレスポンスヘッダーを無効にできます。

@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            // ...
            .headers(headers ->
                headers.disable()
            );
    }
}

必要に応じて、以下の XML 構成ですべての HTTP セキュリティレスポンスヘッダーを無効にできます。

<http>
    <!-- ... -->

    <headers disabled="true" />
</http>

14.2.2 キャッシュ制御

Spring Security には、デフォルトでキャッシュ制御ヘッダーが含まれています。

ただし、実際に特定のレスポンスをキャッシュする場合、アプリケーションは HttpServletResponse.setHeader(String,String): Oracle (英語) を選択的に呼び出して、Spring Security によって設定されたヘッダーをオーバーライドできます。これは、CSS、JavaScript、イメージなどを適切にキャッシュできます。

Spring Web MVC を使用する場合、これは通常、構成内で行われます。これを行う方法の詳細については、Spring リファレンスドキュメントの静的リソースの部分を参照してください。

必要に応じて、Spring Security のキャッシュ制御 HTTP レスポンスヘッダーを無効にすることもできます。

例 14.16: Java 構成で無効化されたキャッシュ制御

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) {
        http
            // ...
            .headers(headers ->
                headers.cacheControl(cache ->
                    cache.disabled()
                )
            );
    }
}

同様に、 <cache-control > 要素を使用して無効にすることができます。

例 14.17: XML で無効化されたキャッシュ制御

<http>
    <!-- ... -->

    <headers>
        <cache-control disabled="true"/>
    </headers>
</http>

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

Spring Security には、デフォルトでコンテンツタイプヘッダーが含まれています。ただし、次の方法で Java 構成で無効にできます。

例 14.18: Java 構成で無効にされたコンテンツタイプオプション

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends
        WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) {
        http
            // ...
            .headers(headers ->
                headers.contentTypeOptions(contentType ->
                    contentType.disabled()
                )
            );
    }
}

同様に、 <content-type-options > 要素を使用して無効にすることができます。

例 14.19: XML で無効にされたコンテンツタイプオプション

<http>
    <!-- ... -->

    <headers>
        <content-type-options disabled="true"/>
    </headers>
</http>

14.2.4 HTTP Strict Transport Security (HSTS)

Spring Security は、デフォルトで Strict Transport Security ヘッダーを提供します。ただし、結果を明示的にカスタマイズできます。例: 以下は、HSTS に Java 構成を明示的に提供する例です。

例 14.20: Java 構成の Strict Transport Security

@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            // ...
            .headers(headers ->
                headers
                    .httpStrictTransportSecurity(hsts ->
                        hsts
                            .includeSubDomains(true)
                            .preload(true)
                            .maxAgeInSeconds(31536000)
                    )
            );
    }
}

同様に、次のように <hsts > 要素を使用して、HSTS に XML 構成を明示的に提供できます。

例 14.21: XML 構成の Strict Transport Security

<http>
    <!-- ... -->

    <headers>
        <hsts
            include-subdomains="true"
            max-age-seconds="31536000"
            preload="true" />
    </headers>
</http>

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

受動性の理由から、Spring Security は HTTP 公開鍵ピンニングのサーブレットサポートを提供しますが 、推奨されません

Java 構成で HPKP ヘッダーを有効にできます。

例 14.22: Java 構成を使用した HTTP 公開鍵ピンニング

@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            // ...
            .headers(headers ->
                headers
                    .httpPublicKeyPinning(hpkp ->
                        hpkp
                            .includeSubDomains(true)
                            .reportUri("https://example.net/pkp-report")
                            .addSha256Pins("d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=", "E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=")
                    )
            );
    }
}

同様に、次のように <hpkp > 要素を使用して HPKP ヘッダーを有効にできます。

例 14.23: XML 構成を使用した HTTP 公開鍵ピンニング

<http>
    <!-- ... -->

    <headers>
        <hpkp
            include-subdomains="true"
            report-uri="https://example.net/pkp-report">
            <pins>
                <pin algorithm="sha256">d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=</pin>
                <pin algorithm="sha256">E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=</pin>
            </pins>
        </hpkp>
    </headers>
</http>

14.2.6 X-Frame-Options

デフォルトでは、Spring Security は X-Frame-Options を使用して iframe 内のレンダリングを無効にします。

以下を使用して、Java オプション内で同じオリジンを使用するようにフレームオプションをカスタマイズできます。

例 14.24: X-Frame-Options: Java 構成の SAMEORIGIN

@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            // ...
            .headers(headers ->
                headers
                    .frameOptions(frameOptions ->
                        frameOptions
                            .sameOrigin()
                    )
            );
    }
}

または、XML 構成内で frame-options 要素を使用できます。

例 14.25: X-Frame-Options: XML 構成を使用した SAMEORIGIN

<http>
    <!-- ... -->

    <headers>
        <frame-options
        policy="SAMEORIGIN" />
    </headers>
</http>

14.2.7 X-XSS-Protection

デフォルトでは、Spring Security は、<< headers-xss-protection、X-XSS-Protection header> を使用して、リフレクションされた XSS 攻撃をブロックするようブラウザーに指示します。ただし、このデフォルトを変更できます。例: 次の Java 構成では、Spring Security がブラウザーにコンテンツをブロックするように指示しないように指定しています。

例 14.26: Java 構成を使用した X-XSS-Protection のカスタマイズ

@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            // ...
            .headers(headers ->
                headers
                    .xssProtection(xssProtection ->
                        xssProtection
                            .block(false)
                    )
            );
    }
}

同様に、次の XML 構成では、Spring Security がブラウザーにコンテンツをブロックするように指示しないように指定しています。

例 14.27: XML 構成を使用した X-XSS-Protection のカスタマイズ

<http>
    <!-- ... -->

    <headers>
        <xss-protection block="false"/>
    </headers>
</http>

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

Spring Security はデフォルトではコンテンツセキュリティポリシーを追加しません。これは、アプリケーションのコンテキストなしでは妥当なデフォルトを知ることが不可能です。Web アプリケーションの作成者は、保護されたリソースを強制または監視するためのセキュリティポリシーを宣言する必要があります。

例: 次のセキュリティポリシーが与えられた場合:

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

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

以下に示すように、Java 構成を使用して CSP ヘッダーを有効にできます。

例 14.29: コンテンツセキュリティポリシーの Java 構成

@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) {
        http
            // ...
            .headers(headers ->
                headers
                    .contentSecurityPolicy(csp ->
                        csp
                            .policyDirectives("script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/")
                    )
            );
    }
}

以下に示すように、 <content-security-policy > 要素を使用して XML 構成を使用しても同じことができます。

例 14.30: コンテンツセキュリティポリシーの Java 構成

<http>
    <!-- ... -->

    <headers>
        <content-security-policy
            policy-directives="script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/" />
    </headers>
</http>

CSP  report-only ヘッダーを有効にするには、次の Java 構成を提供します。

例 14.31: コンテンツセキュリティポリシーレポート Java 構成のみ

@EnableWebSecurity
public class WebSecurityConfig extends
        WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            // ...
            .headers(headers ->
                headers
                    .contentSecurityPolicy(csp ->
                        csp
                            .policyDirectives("script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/")
                            .reportOnly()
                    )
            );
    }
}

同じことは、次を使用した XML 構成でも実現できます。

例 14.32: コンテンツセキュリティポリシーの XML 設定

<http>
    <!-- ... -->

    <headers>
        <content-security-policy
            policy-directives="script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/"
            report-only="true" />
    </headers>
</http>

14.2.9 リファラーポリシー

Spring Security は、デフォルトではリファラーポリシーヘッダーを追加しません。以下に示すように、Java 構成を使用してリファラーポリシーヘッダーを有効にできます。

例 14.33: リファラーポリシー Java 構成

@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) {
        http
            // ...
            .headers(headers ->
                headers
                    .referrerPolicy(referrerPolicy ->
                        referrerPolicy
                            .policy(ReferrerPolicy.SAME_ORIGIN)
                    )
            );
    }
}

以下に示すように、XML 構成と <referrer-policy > 要素を使用して Referrer-Policy ヘッダーを有効にできます。

例 14.34: リファラーポリシー XML 構成

<http>
    <!-- ... -->

    <headers>
        <referrer-policy policy="same-origin" />
    </headers>
</http>

14.2.10 機能ポリシー

Spring Security は、デフォルトでは機能ポリシーヘッダーを追加しません。次の  Feature-Policy ヘッダー:

例 14.35: 機能ポリシーの例

Feature-Policy: geolocation 'self'

以下に示すように、Java 構成を使用して機能ポリシーヘッダーを有効にできます。

例 14.36: 機能ポリシー Java 構成

@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            // ...
            .headers(headers ->
                headers
                    .featurePolicy("geolocation 'self'")
            );
    }
}

または、以下に示すように、 <feature-policy > 要素を含む XML 構成を使用して、Feature-Policy ヘッダーを有効にすることができます。

例 14.37: 機能ポリシー XML 設定

<http>
    <!-- ... -->

    <headers>
        <feature-policy policy-directives="geolocation 'self'" />
    </headers>
</http>

14.2.11 サイトデータを消去する

Spring Security は、デフォルトではクリアサイトデータヘッダーを追加しません。次の Clear-Site-Data ヘッダー:

例 14.38: クリアサイトデータの例

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

ログアウト時に次の構成で送信できます。

例 14.39: Clear-Site-Data Java 構成

@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            // ...
            .logout()
                .addLogoutHandler(new HeaderWriterLogoutHandler(new ClearSiteDataHeaderWriter(CACHE, COOKIES)));
    }
}

14.2.12 カスタムヘッダー

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

静的ヘッダー

すぐにサポートされないカスタムセキュリティヘッダーをアプリケーションに挿入したい場合があります。例: 次のカスタムセキュリティヘッダーを指定します。

X-Custom-Security-Header: header-value

以下に示すように、Java 構成を使用してヘッダーをレスポンスに追加できます。

例 14.40: StaticHeadersWriter Java 構成

@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            // ...
            .headers(headers ->
                headers
                    .addHeaderWriter(new StaticHeadersWriter("X-Custom-Security-Header","header-value"))
            );
    }
}

XML 名前空間を使用する場合、以下に示すように、これらのヘッダーを <header > 要素を使用してレスポンスに追加できます。

例 14.41: StaticHeadersWriter XML 設定

<http>
    <!-- ... -->

    <headers>
        <header name="X-Custom-Security-Header" value="header-value"/>
    </headers>
</http>

ヘッダーライター

名前空間または Java 構成が必要なヘッダーをサポートしていない場合、カスタム  HeadersWriter インスタンスを作成するか、 HeadersWriter のカスタム実装を提供することもできます。

XFrameOptionsHeaderWriter のカスタムインスタンスの使用例を見てみましょう。セクション 14.2.6: “X-Frame-Options” を明示的に構成する場合は、次の Java 構成で実行できます。

例 14.42: ヘッダーライターの Java 構成

@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            // ...
            .headers(headers ->
                headers
                    .addHeaderWriter(new XFrameOptionsHeaderWriter(XFrameOptionsMode.SAMEORIGIN))
            );
    }
}

または、XML ベースの構成に ref 属性を使用できます。

例 14.43: ヘッダーライターの XML 構成

<http>
    <!-- ... -->

    <headers>
        <header ref="frameOptionsWriter"/>
    </headers>
</http>
<!-- Requires the c-namespace.
See https://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-c-namespace
-->
<beans:bean id="frameOptionsWriter"
    class="org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter"
    c:frameOptionsMode="SAMEORIGIN"/>

DelegatingRequestMatcherHeaderWriter

特定のリクエストに対してのみヘッダーを書きたい場合があります。例: おそらく、ログインページをフレームから保護するだけです。そのためには、 DelegatingRequestMatcherHeaderWriter を使用できます。

Java 構成で  DelegatingRequestMatcherHeaderWriter を使用する例を以下に示します。

例 14.44: DelegatingRequestMatcherHeaderWriter Java 構成

@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        RequestMatcher matcher = new AntPathRequestMatcher("/login");
        DelegatingRequestMatcherHeaderWriter headerWriter =
            new DelegatingRequestMatcherHeaderWriter(matcher,new XFrameOptionsHeaderWriter());
        http
            // ...
            .headers(headers ->
                headers
                    .frameOptions(frameOptions ->
                        frameOptions.disable()
                    )
                    .addHeaderWriter(headerWriter)
            );
    }
}

XML ベースの構成でも同じことが実現できます。

例 14.45: DelegatingRequestMatcherHeaderWriter XML 設定

<http>
    <!-- ... -->

    <headers>
        <frame-options disabled="true"/>
        <header ref="headerWriter"/>
    </headers>
</http>

<beans:bean id="headerWriter"
    class="org.springframework.security.web.header.writers.DelegatingRequestMatcherHeaderWriter">
    <beans:constructor-arg>
        <bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher"
            c:pattern="/login"/>
    </beans:constructor-arg>
    <beans:constructor-arg>
        <beans:bean
            class="org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter"/>
    </beans:constructor-arg>
</beans:bean>

14.3 HTTP

すべての HTTP ベースの通信は、 TLS を使用して保護 する 必要があり ます 。

以下に、HTTPS の使用を支援するサーブレット固有の機能に関する詳細を示します。

14.3.1 HTTPS にリダイレクト

クライアントが HTTPS ではなく HTTP を使用してリクエストを行う場合、Spring Security は HTTPS にリダイレクトするように構成できます。

例: 次の Java 構成は、HTTP リクエストを HTTPS にリダイレクトします。

例 14.46: Java 構成で HTTPS にリダイレクトする

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends
        WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) {
        http
            // ...
            .requiresChannel(channel ->
                channel
                    .anyRequest().requiresSecure()
            );
    }
}

次の XML 構成は、すべての HTTP リクエストを HTTPS にリダイレクトする

例 14.47: XML 設定で HTTPS にリダイレクトする

<http>
    <intercept-url pattern="/**" access="ROLE_USER" requires-channel="https"/>
...
</http>

14.3.2 Strict Transport Security

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

14.3.3 プロキシサーバー構成

Spring Security はプロキシサーバーと統合します

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