Skip to content
MDView as Markdown

Spring Boot

Spring Security handles security headers, and CSP is one of the headers it writes. It is not on by default - CSP is the one header Spring Security makes you opt into, because there is no policy that is safe to guess on your behalf.

What Spring Security gives you

  • contentSecurityPolicy() on the headers configuration, taking the policy directives as a string.
  • reportOnly() to emit Content-Security-Policy-Report-Only instead of the enforcing header.
  • ContentSecurityPolicyHeaderWriter underneath, if you need to drive it directly rather than through the DSL.
  • The same directive string is used for whichever header is enabled, so switching between report-only and enforcing does not mean rewriting the policy.

Setting the header

Your URL comes from the Setup page:

@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http.headers(headers -> headers
        .contentSecurityPolicy(csp -> csp
            .policyDirectives("default-src 'self'; object-src 'none'; "
                + "report-uri https://abc123.report-uri.com/r/d/csp/reportOnly")
        )
    );
    return http.build();
}

Add .reportOnly() to the contentSecurityPolicy configuration while you are tuning, then remove it and switch the endpoint to enforce once the reports are clean.

Adding a nonce

Spring Security does not generate CSP nonces for you. If you need one, generate it in a filter, put it in the request attributes so your templates can read it, and build the policy string per request rather than as a constant. With Thymeleaf that means a th:attr="nonce=${cspNonce}" on your inline scripts.

Things to watch for

  • CSP is deliberately not enabled by default. If you assumed Spring Security's defaults covered it, they do not - check for the header before assuming you are protected.
  • The policy is a plain string, so there is no compile-time validation. A typo in a directive name is silently ignored by the browser, which looks identical to the directive working.
  • If you also set the header at a reverse proxy in front of Spring Boot, the browser gets two policies and enforces both. The effective result is the intersection, which is usually more restrictive than either author intended.

Official documentation

Spring Security - Security HTTP Response Headers

Start Monitoring with Report URI

Already using us for CSP? Find your report-uri value on Setup, or view your CSP reports.

New to Report URI? Create an account and grab your report-uri value from the Setup page.

Start your free trial