You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Repeated calls to headers.contentSecurityPolicy(...) should not clobber previous ones #19842
Today, invoking headers.contentSecurityPolicy(...) more than once replaces everything the previous call configured, in both stacks:
Servlet:HeadersConfigurer#contentSecurityPolicy(Customizer) constructs a new ContentSecurityPolicyConfig (and with it a new ContentSecurityPolicyHeaderWriter) on every call.
Reactive:HeaderSpec#contentSecurityPolicy(Customizer) creates a new ContentSecurityPolicySpec, which resets the policy directives (and, with Support nonce-based Content Security Policy #18499, the exchange matcher and nonce filter), while reportOnly is retained.
Other HeadersConfigurer configs let repeated calls compose so this is inconsistent and surprising. This ticket is to look at addressing this inconsistency.
Since this changes behavior for applications that call the method more than once, we may need to wait until the next major unless this can be conceived as a bug.
changed the title [-]Allow repeated headers.contentSecurityPolicy(...) calls to compose instead of replace[/-][+]Repeated calls to headers.contentSecurityPolicy(...) should not clobber previous ones[/+]on Oct 7, 2026
I tend to regard this inconsistency as a bug, especially the chaotic situation in the reactive HeaderSpec.
Usually, people won’t call headers.contentSecurityPolicy(...) multiple times within one SecurityFilterChain bean definition. It might be repeatedly called by accident, however, when multiple modular configurationCustomizer beans are defined in different locations.
By retaining all customizations instead of resetting, unintended repeated calls of headers.contentSecurityPolicy(...) are more likely to be discovered.
The test headersWhenContentSecurityPolicyConfiguredTwiceThenSecondCallReplacesFirst in reactive stack still conflicts with composable headers.contentSecurityPolicy(...).
It is assuming that the second HeaderSpec#contentSecurityPolicy(Customizer) call resets the exchangeMatcher to ServerWebExchangeMatchers.anyExchange(), so that the response to /bar contains CSP default-src 'self' instead of empty CSP.
I've opened #19924 to update headersWhenContentSecurityPolicyConfiguredTwiceThenSecondCallReplacesFirst so that it could test CSP replacement without conflicting with the composition feature.
Activity
[-]Allow repeated headers.contentSecurityPolicy(...) calls to compose instead of replace[/-][+]Repeated calls to headers.contentSecurityPolicy(...) should not clobber previous ones[/+]Allow repeated headers.contentSecurityPolicy(...) calls to compose
ziqin commentedon Oct 9, 2026
I tend to regard this inconsistency as a bug, especially the chaotic situation in the reactive
HeaderSpec.Usually, people won’t call
headers.contentSecurityPolicy(...)multiple times within oneSecurityFilterChainbean definition. It might be repeatedly called by accident, however, when multiple modular configurationCustomizerbeans are defined in different locations.By retaining all customizations instead of resetting, unintended repeated calls of
headers.contentSecurityPolicy(...)are more likely to be discovered.Allow repeated headers.contentSecurityPolicy(...) calls to compose
ziqin commentedon Oct 15, 2026
The test
headersWhenContentSecurityPolicyConfiguredTwiceThenSecondCallReplacesFirstin reactive stack still conflicts with composableheaders.contentSecurityPolicy(...).spring-security/config/src/test/java/org/springframework/security/config/web/server/HeaderSpecTests.java
Lines 529 to 548 in 78c30b7
It is assuming that the second
HeaderSpec#contentSecurityPolicy(Customizer)call resets theexchangeMatchertoServerWebExchangeMatchers.anyExchange(), so that the response to/barcontains CSPdefault-src 'self'instead of empty CSP.This is also why #19864 doesn't pass the CI pipeline.
Related context: #18499 (comment)
ziqin commentedon Oct 17, 2026
I've opened #19924 to update
headersWhenContentSecurityPolicyConfiguredTwiceThenSecondCallReplacesFirstso that it could test CSP replacement without conflicting with the composition feature.Allow repeated headers.contentSecurityPolicy(...) calls to compose