diff --git a/config/src/main/kotlin/org/springframework/security/config/web/servlet/HeadersDsl.kt b/config/src/main/kotlin/org/springframework/security/config/web/servlet/HeadersDsl.kt index 2b3abfe8ee..ae1d9d945e 100644 --- a/config/src/main/kotlin/org/springframework/security/config/web/servlet/HeadersDsl.kt +++ b/config/src/main/kotlin/org/springframework/security/config/web/servlet/HeadersDsl.kt @@ -40,6 +40,7 @@ class HeadersDsl { private var contentSecurityPolicy: ((HeadersConfigurer.ContentSecurityPolicyConfig) -> Unit)? = null private var referrerPolicy: ((HeadersConfigurer.ReferrerPolicyConfig) -> Unit)? = null private var featurePolicyDirectives: String? = null + private var disabled = false var defaultsDisabled: Boolean? = null @@ -161,6 +162,15 @@ class HeadersDsl { this.featurePolicyDirectives = policyDirectives } + /** + * Disable all HTTP security headers. + * + * @since 5.4 + */ + fun disable() { + disabled = true + } + internal fun get(): (HeadersConfigurer) -> Unit { return { headers -> defaultsDisabled?.also { @@ -195,6 +205,9 @@ class HeadersDsl { featurePolicyDirectives?.also { headers.featurePolicy(featurePolicyDirectives) } + if (disabled) { + headers.disable() + } } } } diff --git a/config/src/test/kotlin/org/springframework/security/config/web/servlet/HeadersDslTests.kt b/config/src/test/kotlin/org/springframework/security/config/web/servlet/HeadersDslTests.kt index 7824a7fafe..b535e36b35 100644 --- a/config/src/test/kotlin/org/springframework/security/config/web/servlet/HeadersDslTests.kt +++ b/config/src/test/kotlin/org/springframework/security/config/web/servlet/HeadersDslTests.kt @@ -91,4 +91,31 @@ class HeadersDslTests { } } } + + @Test + fun `request when headers disabled then no security headers are in the response`() { + this.spring.register(HeadersDisabledConfig::class.java).autowire() + + this.mockMvc.get("/") + .andExpect { + header { doesNotExist(ContentTypeOptionsServerHttpHeadersWriter.X_CONTENT_OPTIONS) } + header { doesNotExist(XFrameOptionsServerHttpHeadersWriter.X_FRAME_OPTIONS) } + header { doesNotExist(StrictTransportSecurityServerHttpHeadersWriter.STRICT_TRANSPORT_SECURITY) } + header { doesNotExist(HttpHeaders.CACHE_CONTROL) } + header { doesNotExist(HttpHeaders.EXPIRES) } + header { doesNotExist(HttpHeaders.PRAGMA) } + header { doesNotExist(XXssProtectionServerHttpHeadersWriter.X_XSS_PROTECTION) } + } + } + + @EnableWebSecurity + open class HeadersDisabledConfig : WebSecurityConfigurerAdapter() { + override fun configure(http: HttpSecurity) { + http { + headers { + disable() + } + } + } + } }