Polish content security policy contribution
See gh-7373 See gh-7373
This commit is contained in:
parent
d7bbea63b7
commit
238c22cd73
|
|
@ -175,15 +175,17 @@ public class SecurityProperties implements SecurityPrerequisite {
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ContentSecurityPolicyMode {
|
public enum ContentSecurityPolicyMode {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use the {@code Content-Security-Policy} header.
|
* Use the 'Content-Security-Policy' header.
|
||||||
*/
|
*/
|
||||||
DEFAULT,
|
DEFAULT,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use the {@code Content-Security-Policy-Report-Only} header.
|
* Use the 'Content-Security-Policy-Report-Only' header.
|
||||||
*/
|
*/
|
||||||
REPORT_ONLY
|
REPORT_ONLY
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -212,7 +214,7 @@ public class SecurityProperties implements SecurityPrerequisite {
|
||||||
private String contentSecurityPolicy;
|
private String contentSecurityPolicy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether to use the "Content-Security-Policy" or "Content-Security-Policy-Report-Only" header.
|
* Security policy mode.
|
||||||
*/
|
*/
|
||||||
private ContentSecurityPolicyMode contentSecurityPolicyMode = ContentSecurityPolicyMode.DEFAULT;
|
private ContentSecurityPolicyMode contentSecurityPolicyMode = ContentSecurityPolicyMode.DEFAULT;
|
||||||
|
|
||||||
|
|
@ -265,7 +267,8 @@ public class SecurityProperties implements SecurityPrerequisite {
|
||||||
return this.contentSecurityPolicyMode;
|
return this.contentSecurityPolicyMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setContentSecurityPolicyMode(ContentSecurityPolicyMode contentSecurityPolicyMode) {
|
public void setContentSecurityPolicyMode(
|
||||||
|
ContentSecurityPolicyMode contentSecurityPolicyMode) {
|
||||||
this.contentSecurityPolicyMode = contentSecurityPolicyMode;
|
this.contentSecurityPolicyMode = contentSecurityPolicyMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||||
import org.springframework.boot.autoconfigure.security.SecurityProperties.Headers;
|
import org.springframework.boot.autoconfigure.security.SecurityProperties.Headers;
|
||||||
|
import org.springframework.boot.autoconfigure.security.SecurityProperties.Headers.ContentSecurityPolicyMode;
|
||||||
import org.springframework.boot.autoconfigure.web.ErrorController;
|
import org.springframework.boot.autoconfigure.web.ErrorController;
|
||||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
|
@ -109,12 +110,13 @@ public class SpringBootWebSecurityConfiguration {
|
||||||
configurer.contentTypeOptions().disable();
|
configurer.contentTypeOptions().disable();
|
||||||
}
|
}
|
||||||
if (StringUtils.hasText(headers.getContentSecurityPolicy())) {
|
if (StringUtils.hasText(headers.getContentSecurityPolicy())) {
|
||||||
if (headers.getContentSecurityPolicyMode() == Headers.ContentSecurityPolicyMode.DEFAULT) {
|
String policyDirectives = headers.getContentSecurityPolicy();
|
||||||
configurer.contentSecurityPolicy(headers.getContentSecurityPolicy());
|
ContentSecurityPolicyMode mode = headers.getContentSecurityPolicyMode();
|
||||||
|
if (mode == ContentSecurityPolicyMode.DEFAULT) {
|
||||||
|
configurer.contentSecurityPolicy(policyDirectives);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert headers.getContentSecurityPolicyMode() == Headers.ContentSecurityPolicyMode.REPORT_ONLY;
|
configurer.contentSecurityPolicy(policyDirectives).reportOnly();
|
||||||
configurer.contentSecurityPolicy(headers.getContentSecurityPolicy()).reportOnly();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!headers.isXss()) {
|
if (!headers.isXss()) {
|
||||||
|
|
|
||||||
|
|
@ -214,7 +214,8 @@ public class SpringBootWebSecurityConfigurationTests {
|
||||||
is(notNullValue())))
|
is(notNullValue())))
|
||||||
.andExpect(MockMvcResultMatchers.header().string("X-Frame-Options",
|
.andExpect(MockMvcResultMatchers.header().string("X-Frame-Options",
|
||||||
is(notNullValue())))
|
is(notNullValue())))
|
||||||
.andExpect(MockMvcResultMatchers.header().doesNotExist("Content-Security-Policy"));
|
.andExpect(MockMvcResultMatchers.header()
|
||||||
|
.doesNotExist("Content-Security-Policy"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -250,9 +251,10 @@ public class SpringBootWebSecurityConfigurationTests {
|
||||||
.getBean("springSecurityFilterChain", Filter.class))
|
.getBean("springSecurityFilterChain", Filter.class))
|
||||||
.build();
|
.build();
|
||||||
mockMvc.perform(MockMvcRequestBuilders.get("/"))
|
mockMvc.perform(MockMvcRequestBuilders.get("/"))
|
||||||
.andExpect(MockMvcResultMatchers.header().string("Content-Security-Policy",
|
.andExpect(MockMvcResultMatchers.header()
|
||||||
is("default-src 'self';")))
|
.string("Content-Security-Policy", is("default-src 'self';")))
|
||||||
.andExpect(MockMvcResultMatchers.header().doesNotExist("Content-Security-Policy-Report-Only"));
|
.andExpect(MockMvcResultMatchers.header()
|
||||||
|
.doesNotExist("Content-Security-Policy-Report-Only"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -266,9 +268,10 @@ public class SpringBootWebSecurityConfigurationTests {
|
||||||
.getBean("springSecurityFilterChain", Filter.class))
|
.getBean("springSecurityFilterChain", Filter.class))
|
||||||
.build();
|
.build();
|
||||||
mockMvc.perform(MockMvcRequestBuilders.get("/"))
|
mockMvc.perform(MockMvcRequestBuilders.get("/"))
|
||||||
.andExpect(MockMvcResultMatchers.header().string("Content-Security-Policy-Report-Only",
|
.andExpect(MockMvcResultMatchers.header().string(
|
||||||
is("default-src 'self';")))
|
"Content-Security-Policy-Report-Only", is("default-src 'self';")))
|
||||||
.andExpect(MockMvcResultMatchers.header().doesNotExist("Content-Security-Policy"));
|
.andExpect(MockMvcResultMatchers.header()
|
||||||
|
.doesNotExist("Content-Security-Policy"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue