Missing Content-Security-Policy Header
ID |
java.missing_content_security_policy |
Severity |
low |
Remediation Complexity |
medium |
Remediation Risk |
medium |
Remediation Effort |
medium |
Resource |
Misconfiguration |
Language |
Java |
Tags |
ASVS50:v14.4.3, CWE:693, NIST.SP.800-53, OWASP:2025:A05, spring |
Description
Spring Security configuration sets response headers but does not define a Content-Security-Policy.
Rationale
The Content-Security-Policy (CSP) response header is a strong defence-in-depth control against Cross-Site Scripting (XSS) and data-injection attacks: it lets the application declare which content sources the browser is allowed to load and execute.
Spring Security does not emit a Content-Security-Policy header out of the box. Even when an application customizes its security headers (frame options, content-type options, HSTS, and so on), CSP remains absent unless it is configured explicitly.
A SecurityFilterChain / HttpSecurity configuration that customizes the headers but never calls contentSecurityPolicy(…) therefore ships without any CSP protection, so the browser applies no restriction on script or resource origins.
Remediation
Add a Content-Security-Policy to the headers configuration and tune the policy directives to the resources the application actually needs.
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.headers(headers -> headers
.contentSecurityPolicy(csp -> csp
.policyDirectives("default-src 'self'; script-src 'self'; object-src 'none'")))
.authorizeHttpRequests(auth -> auth.anyRequest().authenticated());
return http.build();
}
Start from a restrictive policy (for example default-src 'self') and relax it only where required. Avoid unsafe-inline and unsafe-eval, and prefer nonces or hashes for any inline scripts that cannot be removed.