Skip to content

Commit 5bc80fc

Browse files
committed
Disable SpEL selector support in WebSocket messaging by default
This commit disables support for evaluating SpEL expressions from untrusted sources by default. Specifically, this applies to the SpEL-based 'selector' header support in WebSocket messaging, which includes the DefaultSubscriptionRegistry and the classes used to configure the 'selector' header name (SimpleBrokerMessageHandler and SimpleBrokerRegistration). The selector header support remains in place but will have to be explicitly enabled beginning with Spring Framework 6.1. For example, a custom implementation of WebSocketMessageBrokerConfigurer can override the configureMessageBroker() method and configure the selector header name as follows. registry.enableSimpleBroker().setSelectorHeaderName("selector"); Closes gh-30550
1 parent 75466fe commit 5bc80fc

File tree

6 files changed

+35
-27
lines changed

6 files changed

+35
-27
lines changed

spring-messaging/src/main/java/org/springframework/messaging/simp/broker/DefaultSubscriptionRegistry.java

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,11 @@
5454
* in memory and uses a {@link org.springframework.util.PathMatcher PathMatcher}
5555
* for matching destinations.
5656
*
57-
* <p>As of 4.2, this class supports a {@link #setSelectorHeaderName selector}
58-
* header on subscription messages with Spring EL expressions evaluated against
59-
* the headers to filter out messages in addition to destination matching.
57+
* <p>This class also supports an optional <em>selector</em> header on subscription
58+
* messages with Spring Expression Language (SpEL) expressions evaluated against
59+
* the headers to filter out messages in addition to destination matching. As of
60+
* Spring Framework 6.1, the SpEL support is disabled by default, but it can be
61+
* enabled by setting a {@linkplain #setSelectorHeaderName selector header name}.
6062
*
6163
* @author Rossen Stoyanchev
6264
* @author Sebastien Deleuze
@@ -79,7 +81,7 @@ public class DefaultSubscriptionRegistry extends AbstractSubscriptionRegistry {
7981
private int cacheLimit = DEFAULT_CACHE_LIMIT;
8082

8183
@Nullable
82-
private String selectorHeaderName = "selector";
84+
private String selectorHeaderName;
8385

8486
private volatile boolean selectorHeaderInUse;
8587

@@ -130,9 +132,11 @@ public int getCacheLimit() {
130132
* <pre style="code">
131133
* headers.foo == 'bar'
132134
* </pre>
133-
* <p>By default this is set to "selector". You can set it to a different
134-
* name, or to {@code null} to turn off support for a selector header.
135-
* @param selectorHeaderName the name to use for a selector header
135+
* <p>By default the selector header name is set to {@code null} which disables
136+
* this feature. You can set it to {@code "selector"} or a different name to
137+
* enable support for a selector header.
138+
* @param selectorHeaderName the name to use for a selector header, or {@code null}
139+
* or blank to disable selector header support
136140
* @since 4.2
137141
*/
138142
public void setSelectorHeaderName(@Nullable String selectorHeaderName) {

spring-messaging/src/main/java/org/springframework/messaging/simp/broker/SimpleBrokerMessageHandler.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public class SimpleBrokerMessageHandler extends AbstractBrokerMessageHandler {
6161
private Integer cacheLimit;
6262

6363
@Nullable
64-
private String selectorHeaderName = "selector";
64+
private String selectorHeaderName;
6565

6666
@Nullable
6767
private TaskScheduler taskScheduler;
@@ -172,11 +172,13 @@ private void initCacheLimitToUse() {
172172
* <pre style="code">
173173
* headers.foo == 'bar'
174174
* </pre>
175-
* <p>By default this is set to "selector". You can set it to a different
176-
* name, or to {@code null} to turn off support for a selector header.
175+
* <p>By default the selector header name is set to {@code null} which disables
176+
* this feature. You can set it to {@code "selector"} or a different name to
177+
* enable support for a selector header.
177178
* <p>Setting this property has no effect if the underlying SubscriptionRegistry
178179
* is not an instance of {@link DefaultSubscriptionRegistry}.
179-
* @param selectorHeaderName the name to use for a selector header
180+
* @param selectorHeaderName the name to use for a selector header, or {@code null}
181+
* or blank to disable selector header support
180182
* @since 4.3.17
181183
* @see #setSubscriptionRegistry
182184
* @see DefaultSubscriptionRegistry#setSelectorHeaderName(String)

spring-messaging/src/main/java/org/springframework/messaging/simp/config/SimpleBrokerRegistration.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public class SimpleBrokerRegistration extends AbstractBrokerRegistration {
3838
private long[] heartbeat;
3939

4040
@Nullable
41-
private String selectorHeaderName = "selector";
41+
private String selectorHeaderName;
4242

4343

4444
/**
@@ -90,9 +90,11 @@ public SimpleBrokerRegistration setHeartbeatValue(long[] heartbeat) {
9090
* <pre style="code">
9191
* headers.foo == 'bar'
9292
* </pre>
93-
* <p>By default this is set to "selector". You can set it to a different
94-
* name, or to {@code null} to turn off support for a selector header.
95-
* @param selectorHeaderName the name to use for a selector header
93+
* <p>By default the selector header name is set to {@code null} which disables
94+
* this feature. You can set it to {@code "selector"} or a different name to
95+
* enable support for a selector header.
96+
* @param selectorHeaderName the name to use for a selector header, or {@code null}
97+
* or blank to disable selector header support
9698
* @since 4.3.17
9799
*/
98100
public void setSelectorHeaderName(@Nullable String selectorHeaderName) {

spring-messaging/src/test/java/org/springframework/messaging/simp/broker/DefaultSubscriptionRegistryTests.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ void registerSubscriptionWithDestinationPatternRegex() {
253253
}
254254

255255
@Test
256-
void registerSubscriptionWithSelectorHeaderEnabledByDefault() {
256+
void registerSubscriptionWithSelectorHeaderEnabled() {
257257
String sessionId1 = "sess01";
258258
String sessionId2 = "sess02";
259259
String sessionId3 = "sess03";
@@ -264,6 +264,9 @@ void registerSubscriptionWithSelectorHeaderEnabledByDefault() {
264264
String selector1 = "headers.foo == 'bar'";
265265
String selector2 = "headers.foo == 'enigma'";
266266

267+
// Explicitly enable selector support
268+
this.registry.setSelectorHeaderName("selector");
269+
267270
// Register subscription with matching selector header
268271
this.registry.registerSubscription(subscribeMessage(sessionId1, subscriptionId1, destination, selector1));
269272
// Register subscription with non-matching selector header
@@ -297,7 +300,7 @@ void registerSubscriptionWithSelectorHeaderEnabledByDefault() {
297300
}
298301

299302
@Test
300-
void registerSubscriptionWithSelectorHeaderDisabled() {
303+
void registerSubscriptionWithSelectorHeaderDisabledByDefault() {
301304
String sessionId1 = "sess01";
302305
String sessionId2 = "sess02";
303306
String sessionId3 = "sess03";
@@ -308,9 +311,6 @@ void registerSubscriptionWithSelectorHeaderDisabled() {
308311
String selector1 = "headers.foo == 'bar'";
309312
String selector2 = "headers.foo == 'enigma'";
310313

311-
// Explicitly disable selector header support
312-
this.registry.setSelectorHeaderName(null);
313-
314314
// Register subscription with matching selector header
315315
this.registry.registerSubscription(subscribeMessage(sessionId1, subscriptionId1, destination, selector1));
316316
// Register subscription with non-matching selector header

spring-websocket/src/test/java/org/springframework/web/socket/config/annotation/WebSocketMessageBrokerConfigurationSupportTests.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,8 @@ void taskScheduler() {
165165
}
166166

167167
@Test
168-
void selectorHeaderEnabledByDefault() {
169-
ApplicationContext context = createContext(TestChannelConfig.class, TestConfigurer.class);
168+
void selectorHeaderEnabled() {
169+
ApplicationContext context = createContext(TestChannelConfig.class, SelectorHeaderConfigurer.class);
170170
SimpleBrokerMessageHandler simpleBrokerMessageHandler = simpleBrokerMessageHandler(context);
171171

172172
assertThat(simpleBrokerMessageHandler.getSubscriptionRegistry())
@@ -176,8 +176,8 @@ void selectorHeaderEnabledByDefault() {
176176
}
177177

178178
@Test
179-
void selectorHeaderDisabled() {
180-
ApplicationContext context = createContext(TestChannelConfig.class, SelectorHeaderConfigurer.class);
179+
void selectorHeaderDisabledByDefault() {
180+
ApplicationContext context = createContext(TestChannelConfig.class, TestConfigurer.class);
181181
SimpleBrokerMessageHandler simpleBrokerMessageHandler = simpleBrokerMessageHandler(context);
182182

183183
assertThat(simpleBrokerMessageHandler.getSubscriptionRegistry())
@@ -282,8 +282,8 @@ public void registerStompEndpoints(StompEndpointRegistry registry) {
282282

283283
@Override
284284
public void configureMessageBroker(MessageBrokerRegistry registry) {
285-
// Explicitly disable selector header support
286-
registry.enableSimpleBroker().setSelectorHeaderName(null);
285+
// Explicitly enable selector header support
286+
registry.enableSimpleBroker().setSelectorHeaderName("selector");
287287
}
288288

289289
}

spring-websocket/src/test/java/org/springframework/web/socket/messaging/StompWebSocketIntegrationTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ public void registerStompEndpoints(StompEndpointRegistry registry) {
320320
@Override
321321
public void configureMessageBroker(MessageBrokerRegistry configurer) {
322322
configurer.setApplicationDestinationPrefixes("/app");
323-
configurer.enableSimpleBroker("/topic", "/queue");
323+
configurer.enableSimpleBroker("/topic", "/queue").setSelectorHeaderName("selector");
324324
}
325325

326326
@Bean

0 commit comments

Comments
 (0)