-
Notifications
You must be signed in to change notification settings - Fork 6.2k
Description
Describe the bug
When configuring WebSocket message security via Spring Security's XML support, a CsrfChannelInterceptor is configured but the default CSRF handler in the web layer is generated by the XorCsrfTokenRequestAttributeHandler, so STOMP CONNECT messages that present the XOR'd CSRF value are rejected as a mismatch.
To Reproduce
Configure WebSocket security via XML with basic defaults, for example:
<websocket-message-broker>
<intercept-message type="CONNECT" access="permitAll" />
<intercept-message type="UNSUBSCRIBE" access="permitAll" />
<intercept-message type="DISCONNECT" access="permitAll" />
<intercept-message pattern="/pub/**" access="permitAll" />
<intercept-message pattern="/**" access="hasRole('USER')" />
</websocket-message-broker>When a client that has authenticated successfully with Spring Security tries to issue a STOMP CONNECT request, passing in the active session-based CSRF value generated by Spring Security's .web.csrf.XorCsrfTokenRequestAttributeHandler the message is rejected and the connection terminated.
Expected behavior
I thought Spring Security 6 could switch to defaulting to .messaging.web.csrf.XorCsrfChannelInterceptor now instead of .messaging.web.csrf.CsrfChannelInterceptor, in WebSocketMessageBrokerSecurityBeanDefinitionParser e.g.
if (!this.sameOriginDisabled) {
interceptors.add(new RootBeanDefinition(XorCsrfChannelInterceptor.class));
}Work-around
I couldn't find a simple way to use XorCsrfChannelInterceptor so I added a basic BeanPostProcessor to my application that replaced the CsrfChannelInterceptor instance with an XorCsrfChannelInterceptor instance on the ExecutorSubscribableChannel bean.