Skip to content

Commit 87e0151

Browse files
committed
Check SockJS session type
This commits adds a validation check whether the SockJS session type matches the transport type and rejects requests for which they don't match. Issue: SPR-14867
1 parent 8705df5 commit 87e0151

File tree

10 files changed

+65
-4
lines changed

10 files changed

+65
-4
lines changed

spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/TransportHandler.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2013 the original author or authors.
2+
* Copyright 2002-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -43,6 +43,14 @@ public interface TransportHandler {
4343
*/
4444
TransportType getTransportType();
4545

46+
/**
47+
* Whether the type of the given session matches the transport type of this
48+
* {@code TransportHandler} where session id and the transport type are
49+
* extracted from the SockJS URL.
50+
* @since 4.3.3
51+
*/
52+
boolean checkSessionType(SockJsSession session);
53+
4654
/**
4755
* Handle the given request and delegate messages to the provided
4856
* {@link WebSocketHandler}.

spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/TransportHandlingSockJsService.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,11 @@ else if (transportType.supportsCors()) {
291291
return;
292292
}
293293
}
294+
if (!transportHandler.checkSessionType(session)) {
295+
logger.debug("Session type does not match the transport type for the request.");
296+
response.setStatusCode(HttpStatus.NOT_FOUND);
297+
return;
298+
}
294299
}
295300

296301
if (transportType.sendsNoCacheInstruction()) {
@@ -303,7 +308,10 @@ else if (transportType.supportsCors()) {
303308
}
304309
}
305310

311+
306312
transportHandler.handleRequest(request, response, handler, session);
313+
314+
307315
chain.applyAfterHandshake(request, response, null);
308316
}
309317
catch (SockJsException ex) {

spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/AbstractHttpReceivingTransportHandler.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,4 +99,9 @@ private void handleReadError(ServerHttpResponse response, String error, String s
9999

100100
protected abstract HttpStatus getResponseStatus();
101101

102+
@Override
103+
public boolean checkSessionType(SockJsSession session) {
104+
return session instanceof AbstractHttpSockJsSession;
105+
}
106+
102107
}

spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/EventSourceTransportHandler.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@
2525
import org.springframework.web.socket.sockjs.frame.DefaultSockJsFrameFormat;
2626
import org.springframework.web.socket.sockjs.frame.SockJsFrameFormat;
2727
import org.springframework.web.socket.sockjs.transport.SockJsServiceConfig;
28+
import org.springframework.web.socket.sockjs.transport.SockJsSession;
2829
import org.springframework.web.socket.sockjs.transport.TransportType;
30+
import org.springframework.web.socket.sockjs.transport.session.PollingSockJsSession;
2931
import org.springframework.web.socket.sockjs.transport.session.StreamingSockJsSession;
3032

3133
/**
@@ -47,6 +49,11 @@ protected MediaType getContentType() {
4749
return new MediaType("text", "event-stream", StandardCharsets.UTF_8);
4850
}
4951

52+
@Override
53+
public boolean checkSessionType(SockJsSession session) {
54+
return session instanceof EventSourceStreamingSockJsSession;
55+
}
56+
5057
@Override
5158
public StreamingSockJsSession createSession(
5259
String sessionId, WebSocketHandler handler, Map<String, Object> attributes) {

spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/HtmlFileTransportHandler.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,11 @@
3232
import org.springframework.web.socket.sockjs.frame.DefaultSockJsFrameFormat;
3333
import org.springframework.web.socket.sockjs.frame.SockJsFrameFormat;
3434
import org.springframework.web.socket.sockjs.transport.SockJsServiceConfig;
35+
import org.springframework.web.socket.sockjs.transport.SockJsSession;
3536
import org.springframework.web.socket.sockjs.transport.TransportHandler;
3637
import org.springframework.web.socket.sockjs.transport.TransportType;
3738
import org.springframework.web.socket.sockjs.transport.session.AbstractHttpSockJsSession;
39+
import org.springframework.web.socket.sockjs.transport.session.PollingSockJsSession;
3840
import org.springframework.web.socket.sockjs.transport.session.StreamingSockJsSession;
3941
import org.springframework.web.util.JavaScriptUtils;
4042

@@ -88,6 +90,11 @@ protected MediaType getContentType() {
8890
return new MediaType("text", "html", StandardCharsets.UTF_8);
8991
}
9092

93+
@Override
94+
public boolean checkSessionType(SockJsSession session) {
95+
return session instanceof HtmlFileStreamingSockJsSession;
96+
}
97+
9198
@Override
9299
public StreamingSockJsSession createSession(
93100
String sessionId, WebSocketHandler handler, Map<String, Object> attributes) {

spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/JsonpPollingTransportHandler.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.springframework.web.socket.sockjs.SockJsTransportFailureException;
3131
import org.springframework.web.socket.sockjs.frame.DefaultSockJsFrameFormat;
3232
import org.springframework.web.socket.sockjs.frame.SockJsFrameFormat;
33+
import org.springframework.web.socket.sockjs.transport.SockJsSession;
3334
import org.springframework.web.socket.sockjs.transport.TransportType;
3435
import org.springframework.web.socket.sockjs.transport.session.AbstractHttpSockJsSession;
3536
import org.springframework.web.socket.sockjs.transport.session.PollingSockJsSession;
@@ -53,6 +54,11 @@ protected MediaType getContentType() {
5354
return new MediaType("application", "javascript", StandardCharsets.UTF_8);
5455
}
5556

57+
@Override
58+
public boolean checkSessionType(SockJsSession session) {
59+
return session instanceof PollingSockJsSession;
60+
}
61+
5662
@Override
5763
public PollingSockJsSession createSession(
5864
String sessionId, WebSocketHandler handler, Map<String, Object> attributes) {

spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/WebSocketTransportHandler.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2015 the original author or authors.
2+
* Copyright 2002-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -103,6 +103,11 @@ public void stop() {
103103
}
104104
}
105105

106+
@Override
107+
public boolean checkSessionType(SockJsSession session) {
108+
return session instanceof WebSocketServerSockJsSession;
109+
}
110+
106111
@Override
107112
public AbstractSockJsSession createSession(String id, WebSocketHandler handler, Map<String, Object> attrs) {
108113
return new WebSocketServerSockJsSession(id, getServiceConfig(), handler, attrs);

spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/XhrPollingTransportHandler.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@
2424
import org.springframework.web.socket.WebSocketHandler;
2525
import org.springframework.web.socket.sockjs.frame.DefaultSockJsFrameFormat;
2626
import org.springframework.web.socket.sockjs.frame.SockJsFrameFormat;
27+
import org.springframework.web.socket.sockjs.transport.SockJsSession;
2728
import org.springframework.web.socket.sockjs.transport.TransportHandler;
2829
import org.springframework.web.socket.sockjs.transport.TransportType;
30+
import org.springframework.web.socket.sockjs.transport.session.AbstractHttpSockJsSession;
2931
import org.springframework.web.socket.sockjs.transport.session.PollingSockJsSession;
3032

3133
/**
@@ -51,6 +53,11 @@ protected SockJsFrameFormat getFrameFormat(ServerHttpRequest request) {
5153
return new DefaultSockJsFrameFormat("%s\n");
5254
}
5355

56+
@Override
57+
public boolean checkSessionType(SockJsSession session) {
58+
return session instanceof PollingSockJsSession;
59+
}
60+
5461
@Override
5562
public PollingSockJsSession createSession(
5663
String sessionId, WebSocketHandler handler, Map<String, Object> attributes) {

spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/XhrStreamingTransportHandler.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@
2525
import org.springframework.web.socket.sockjs.frame.DefaultSockJsFrameFormat;
2626
import org.springframework.web.socket.sockjs.frame.SockJsFrameFormat;
2727
import org.springframework.web.socket.sockjs.transport.SockJsServiceConfig;
28+
import org.springframework.web.socket.sockjs.transport.SockJsSession;
2829
import org.springframework.web.socket.sockjs.transport.TransportHandler;
2930
import org.springframework.web.socket.sockjs.transport.TransportType;
31+
import org.springframework.web.socket.sockjs.transport.session.PollingSockJsSession;
3032
import org.springframework.web.socket.sockjs.transport.session.StreamingSockJsSession;
3133

3234
/**
@@ -57,6 +59,11 @@ protected MediaType getContentType() {
5759
return new MediaType("application", "javascript", StandardCharsets.UTF_8);
5860
}
5961

62+
@Override
63+
public boolean checkSessionType(SockJsSession session) {
64+
return session instanceof XhrStreamingSockJsSession;
65+
}
66+
6067
@Override
6168
public StreamingSockJsSession createSession(
6269
String sessionId, WebSocketHandler handler, Map<String, Object> attributes) {

spring-websocket/src/test/java/org/springframework/web/socket/sockjs/transport/handler/DefaultSockJsServiceTests.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2015 the original author or authors.
2+
* Copyright 2002-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -44,7 +44,7 @@
4444
import static org.mockito.BDDMockito.*;
4545

4646
/**
47-
* Test fixture for {@link org.springframework.web.socket.sockjs.transport.handler.DefaultSockJsService}.
47+
* Test fixture for {@link DefaultSockJsService}.
4848
*
4949
* @author Rossen Stoyanchev
5050
* @author Sebastien Deleuze
@@ -239,6 +239,7 @@ public void handleTransportRequestXhrSend() throws Exception {
239239
resetResponse();
240240
sockJsPath = sessionUrlPrefix + "xhr_send";
241241
setRequest("POST", sockJsPrefix + sockJsPath);
242+
given(this.xhrSendHandler.checkSessionType(this.session)).willReturn(true);
242243
this.service.handleRequest(this.request, this.response, sockJsPath, this.wsHandler);
243244

244245
assertEquals(200, this.servletResponse.getStatus()); // session exists

0 commit comments

Comments
 (0)