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

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

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

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

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

これは、次の構成で実行できます。

デフォルトのセキュリティヘッダーのカスタマイズ
  • Java

  • Kotlin

@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
	http
		// ...
		.headers(headers -> headers
			.frameOptions(frameOptions -> frameOptions
				.mode(Mode.SAMEORIGIN)
			)
		);
	return http.build();
}
@Bean
fun webFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
    return http {
        // ...
        headers {
            frameOptions {
                mode = Mode.SAMEORIGIN
            }
        }
    }
}

デフォルトを追加せず、何を使用するかを明示的に制御したい場合は、デフォルトを無効にすることができます。

HTTP セキュリティレスポンスヘッダーを無効にする
  • Java

  • Kotlin

@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
	http
		// ...
		.headers(headers -> headers.disable());
	return http.build();
}
@Bean
fun webFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
    return http {
        // ...
        headers {
            disable()
        }
    }
}

キャッシュ制御

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

ただし、実際に特定のレスポンスをキャッシュする場合は、アプリケーションで ServerHttpResponse (Javadoc) に選択的に追加して、Spring Security によって設定されたヘッダーをオーバーライドできます。これは、CSS、JavaScript、イメージなどが適切にキャッシュされるようにするために役立ちます。

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

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

キャッシュ制御が無効
  • Java

  • Kotlin

@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
	http
		// ...
		.headers(headers -> headers
			.cache(cache -> cache.disable())
		);
	return http.build();
}
@Bean
fun webFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
    return http {
        // ...
        headers {
            cache {
                disable()
            }
        }
    }
}

コンテンツ型オプション

デフォルトでは、Spring Security にはコンテンツ型ヘッダーが含まれています。ただし、無効にすることができます。

コンテンツ型オプションが無効
  • Java

  • Kotlin

@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
	http
		// ...
		.headers(headers -> headers
			.contentTypeOptions(contentTypeOptions -> contentTypeOptions.disable())
		);
	return http.build();
}
@Bean
fun webFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
    return http {
        // ...
        headers {
            contentTypeOptions {
                disable()
            }
        }
    }
}

HTTP Strict Transport Security (HSTS)

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

Strict Transport Security
  • Java

  • Kotlin

@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
	http
		// ...
		.headers(headers -> headers
			.hsts(hsts -> hsts
				.includeSubdomains(true)
				.preload(true)
				.maxAge(Duration.ofDays(365))
			)
		);
	return http.build();
}
@Bean
fun webFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
    return http {
        // ...
        headers {
            hsts {
                includeSubdomains = true
                preload = true
                maxAge = Duration.ofDays(365)
            }
        }
    }
}

X-Frame-Options

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

同じ原点を使用するようにフレームオプションをカスタマイズできます。

X-Frame-Options: SAMEORIGIN
  • Java

  • Kotlin

@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
	http
		// ...
		.headers(headers -> headers
			.frameOptions(frameOptions -> frameOptions
				.mode(SAMEORIGIN)
			)
		);
	return http.build();
}
@Bean
fun webFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
    return http {
        // ...
        headers {
            frameOptions {
                mode = SAMEORIGIN
            }
        }
    }
}

X-XSS-Protection

デフォルトでは、Spring Security はブラウザーに <<headers-xss-protection,X-XSS-Protection header> を使用して XSS Auditor を無効にするように指示します。X-XSS-Protection ヘッダーを完全に無効にすることができます。

X-XSS-Protection のカスタマイズ
  • Java

  • Kotlin

@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
	http
		// ...
		.headers(headers -> headers
			.xssProtection(xssProtection -> xssProtection.disable())
		);
	return http.build();
}
@Bean
fun webFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
    return http {
        // ...
        headers {
            xssProtection {
                disable()
            }
        }
    }
}

ヘッダー値を変更することもできます。

X-XSS-Protection Explicit ヘッダー値
  • Java

  • Kotlin

@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
	http
		// ...
		.headers(headers -> headers
			.xssProtection(xssProtection -> xssProtection.headerValue(XXssProtectionServerHttpHeadersWriter.HeaderValue.ENABLED_MODE_BLOCK))
		);
	return http.build();
}
@Bean
fun webFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
    return http {
        // ...
        headers {
            xssProtection {
                headerValue = XXssProtectionServerHttpHeadersWriter.HeaderValue.ENABLED_MODE_BLOCK
            }
        }
    }
}

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

デフォルトでは、Spring Security はコンテンツセキュリティポリシーを追加しません。これは、アプリケーションのコンテキストがないと、適切なデフォルトを知ることができないためです。Web アプリケーションの作成者は、保護されたリソースを適用および / または監視するためのセキュリティポリシーを宣言する必要があります。

例: 次のセキュリティポリシーを検討してください。

コンテンツセキュリティポリシーの例
Content-Security-Policy: script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/

上記のポリシーを前提として、CSP ヘッダーを有効にできます。

コンテンツセキュリティポリシー
  • Java

  • Kotlin

@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
	http
		// ...
		.headers(headers -> headers
			.contentSecurityPolicy(policy -> policy
				.policyDirectives("script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/")
			)
		);
	return http.build();
}
@Bean
fun webFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
    return http {
        // ...
        headers {
            contentSecurityPolicy {
                policyDirectives = "script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/"
            }
        }
    }
}

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

コンテンツセキュリティポリシーレポートのみ
  • Java

  • Kotlin

@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
	http
		// ...
		.headers(headers -> headers
			.contentSecurityPolicy(policy -> policy
				.policyDirectives("script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/")
				.reportOnly()
			)
		);
	return http.build();
}
@Bean
fun webFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
    return http {
        // ...
        headers {
            contentSecurityPolicy {
                policyDirectives = "script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/"
                reportOnly = true
            }
        }
    }
}

リファラーポリシー

Spring Security は、ディレクティブ no-referrer を使用してデフォルトでリファラーポリシーヘッダーを追加します。以下に示すように構成を使用して、リファラーポリシーヘッダーを変更できます。

リファラーポリシーの構成
  • Java

  • Kotlin

@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
	http
		// ...
		.headers(headers -> headers
			.referrerPolicy(referrer -> referrer
				.policy(ReferrerPolicy.SAME_ORIGIN)
			)
		);
	return http.build();
}
@Bean
fun webFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
    return http {
        // ...
        headers {
            referrerPolicy {
                policy = ReferrerPolicy.SAME_ORIGIN
            }
        }
    }
}

機能ポリシー

デフォルトでは、Spring Security は機能ポリシーヘッダーを追加しません。次の Feature-Policy ヘッダーについて考えてみます。

機能ポリシーの例
Feature-Policy: geolocation 'self'

上記の機能ポリシーヘッダーを有効にできます。

機能ポリシーの構成
  • Java

  • Kotlin

@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
	http
		// ...
		.headers(headers -> headers
			.featurePolicy("geolocation 'self'")
		);
	return http.build();
}
@Bean
fun webFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
    return http {
        // ...
        headers {
            featurePolicy("geolocation 'self'")
        }
    }
}

権限ポリシー

デフォルトでは、Spring Security は権限ポリシーヘッダーを追加しません。次の Permissions-Policy ヘッダーについて考えてみます。

権限 - ポリシーの例
Permissions-Policy: geolocation=(self)

上記のパーミッションポリシーヘッダーを有効にできます。

権限 - ポリシー構成
  • Java

  • Kotlin

@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
	http
		// ...
		.headers(headers -> headers
			.permissionsPolicy(permissions -> permissions
				.policy("geolocation=(self)")
			)
		);
	return http.build();
}
@Bean
fun webFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
    return http {
        // ...
        headers {
            permissionsPolicy {
                policy = "geolocation=(self)"
            }
        }
    }
}

サイトデータのクリア

デフォルトでは、Spring Security は Clear-Site-Data ヘッダーを追加しません。次の Clear-Site-Data ヘッダーについて考えてみます。

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

ログアウト時に Clear-Site-Data ヘッダーを送信できます。

Clear-Site-Data の設定
  • Java

  • Kotlin

@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
	ServerLogoutHandler securityContext = new SecurityContextServerLogoutHandler();
	ClearSiteDataServerHttpHeadersWriter writer = new ClearSiteDataServerHttpHeadersWriter(CACHE, COOKIES);
	ServerLogoutHandler clearSiteData = new HeaderWriterServerLogoutHandler(writer);
	DelegatingServerLogoutHandler logoutHandler = new DelegatingServerLogoutHandler(securityContext, clearSiteData);

	http
		// ...
		.logout()
			.logoutHandler(logoutHandler);
	return http.build();
}
@Bean
fun webFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
    val securityContext: ServerLogoutHandler = SecurityContextServerLogoutHandler()
    val writer = ClearSiteDataServerHttpHeadersWriter(CACHE, COOKIES)
    val clearSiteData: ServerLogoutHandler = HeaderWriterServerLogoutHandler(writer)
    val customLogoutHandler = DelegatingServerLogoutHandler(securityContext, clearSiteData)

    return http {
        // ...
        logout {
            logoutHandler = customLogoutHandler
        }
    }
}