Skip to content

Commit 8f4ec35

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 17863df commit 8f4ec35

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
@@ -98,4 +98,9 @@ private void handleReadError(ServerHttpResponse response, String error, String s
9898

9999
protected abstract HttpStatus getResponseStatus();
100100

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

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
@@ -24,7 +24,9 @@
2424
import org.springframework.web.socket.sockjs.frame.DefaultSockJsFrameFormat;
2525
import org.springframework.web.socket.sockjs.frame.SockJsFrameFormat;
2626
import org.springframework.web.socket.sockjs.transport.SockJsServiceConfig;
27+
import org.springframework.web.socket.sockjs.transport.SockJsSession;
2728
import org.springframework.web.socket.sockjs.transport.TransportType;
29+
import org.springframework.web.socket.sockjs.transport.session.PollingSockJsSession;
2830
import org.springframework.web.socket.sockjs.transport.session.StreamingSockJsSession;
2931

3032
/**
@@ -46,6 +48,11 @@ protected MediaType getContentType() {
4648
return new MediaType("text", "event-stream", UTF8_CHARSET);
4749
}
4850

51+
@Override
52+
public boolean checkSessionType(SockJsSession session) {
53+
return session instanceof EventSourceStreamingSockJsSession;
54+
}
55+
4956
@Override
5057
public StreamingSockJsSession createSession(
5158
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
@@ -31,9 +31,11 @@
3131
import org.springframework.web.socket.sockjs.frame.DefaultSockJsFrameFormat;
3232
import org.springframework.web.socket.sockjs.frame.SockJsFrameFormat;
3333
import org.springframework.web.socket.sockjs.transport.SockJsServiceConfig;
34+
import org.springframework.web.socket.sockjs.transport.SockJsSession;
3435
import org.springframework.web.socket.sockjs.transport.TransportHandler;
3536
import org.springframework.web.socket.sockjs.transport.TransportType;
3637
import org.springframework.web.socket.sockjs.transport.session.AbstractHttpSockJsSession;
38+
import org.springframework.web.socket.sockjs.transport.session.PollingSockJsSession;
3739
import org.springframework.web.socket.sockjs.transport.session.StreamingSockJsSession;
3840
import org.springframework.web.util.JavaScriptUtils;
3941

@@ -87,6 +89,11 @@ protected MediaType getContentType() {
8789
return new MediaType("text", "html", UTF8_CHARSET);
8890
}
8991

92+
@Override
93+
public boolean checkSessionType(SockJsSession session) {
94+
return session instanceof HtmlFileStreamingSockJsSession;
95+
}
96+
9097
@Override
9198
public StreamingSockJsSession createSession(
9299
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
@@ -29,6 +29,7 @@
2929
import org.springframework.web.socket.sockjs.SockJsTransportFailureException;
3030
import org.springframework.web.socket.sockjs.frame.DefaultSockJsFrameFormat;
3131
import org.springframework.web.socket.sockjs.frame.SockJsFrameFormat;
32+
import org.springframework.web.socket.sockjs.transport.SockJsSession;
3233
import org.springframework.web.socket.sockjs.transport.TransportType;
3334
import org.springframework.web.socket.sockjs.transport.session.AbstractHttpSockJsSession;
3435
import org.springframework.web.socket.sockjs.transport.session.PollingSockJsSession;
@@ -52,6 +53,11 @@ protected MediaType getContentType() {
5253
return new MediaType("application", "javascript", UTF8_CHARSET);
5354
}
5455

56+
@Override
57+
public boolean checkSessionType(SockJsSession session) {
58+
return session instanceof PollingSockJsSession;
59+
}
60+
5561
@Override
5662
public PollingSockJsSession createSession(
5763
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
@@ -23,8 +23,10 @@
2323
import org.springframework.web.socket.WebSocketHandler;
2424
import org.springframework.web.socket.sockjs.frame.DefaultSockJsFrameFormat;
2525
import org.springframework.web.socket.sockjs.frame.SockJsFrameFormat;
26+
import org.springframework.web.socket.sockjs.transport.SockJsSession;
2627
import org.springframework.web.socket.sockjs.transport.TransportHandler;
2728
import org.springframework.web.socket.sockjs.transport.TransportType;
29+
import org.springframework.web.socket.sockjs.transport.session.AbstractHttpSockJsSession;
2830
import org.springframework.web.socket.sockjs.transport.session.PollingSockJsSession;
2931

3032
/**
@@ -50,6 +52,11 @@ protected SockJsFrameFormat getFrameFormat(ServerHttpRequest request) {
5052
return new DefaultSockJsFrameFormat("%s\n");
5153
}
5254

55+
@Override
56+
public boolean checkSessionType(SockJsSession session) {
57+
return session instanceof PollingSockJsSession;
58+
}
59+
5360
@Override
5461
public PollingSockJsSession createSession(
5562
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
@@ -24,8 +24,10 @@
2424
import org.springframework.web.socket.sockjs.frame.DefaultSockJsFrameFormat;
2525
import org.springframework.web.socket.sockjs.frame.SockJsFrameFormat;
2626
import org.springframework.web.socket.sockjs.transport.SockJsServiceConfig;
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.PollingSockJsSession;
2931
import org.springframework.web.socket.sockjs.transport.session.StreamingSockJsSession;
3032

3133
/**
@@ -56,6 +58,11 @@ protected MediaType getContentType() {
5658
return new MediaType("application", "javascript", UTF8_CHARSET);
5759
}
5860

61+
@Override
62+
public boolean checkSessionType(SockJsSession session) {
63+
return session instanceof XhrStreamingSockJsSession;
64+
}
65+
5966
@Override
6067
public StreamingSockJsSession createSession(
6168
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)