Skip to content

Commit 299b776

Browse files
committed
Allow same-origin WebSocket/SockJS requests once origin is set
Issue: SPR-13464
1 parent f60bd25 commit 299b776

File tree

5 files changed

+38
-7
lines changed

5 files changed

+38
-7
lines changed

spring-websocket/src/main/java/org/springframework/web/socket/server/support/OriginHandshakeInterceptor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ public Collection<String> getAllowedOrigins() {
9393
@Override
9494
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,
9595
WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
96-
if (!WebUtils.isValidOrigin(request, this.allowedOrigins)) {
96+
if (!WebUtils.isSameOrigin(request) && !WebUtils.isValidOrigin(request, this.allowedOrigins)) {
9797
response.setStatusCode(HttpStatus.FORBIDDEN);
9898
if (logger.isDebugEnabled()) {
9999
logger.debug("Handshake request rejected, Origin header value "

spring-websocket/src/main/java/org/springframework/web/socket/sockjs/support/AbstractSockJsService.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -448,13 +448,12 @@ protected abstract void handleTransportRequest(ServerHttpRequest request, Server
448448
protected boolean checkOrigin(ServerHttpRequest request, ServerHttpResponse response,
449449
HttpMethod... httpMethods) throws IOException {
450450

451-
String origin = request.getHeaders().getOrigin();
452-
453-
if (origin == null) {
451+
if (WebUtils.isSameOrigin(request)) {
454452
return true;
455453
}
456454

457455
if (!WebUtils.isValidOrigin(request, this.allowedOrigins)) {
456+
String origin = request.getHeaders().getOrigin();
458457
logger.debug("Request rejected, Origin header value " + origin + " not allowed");
459458
response.setStatusCode(HttpStatus.FORBIDDEN);
460459
return false;

spring-websocket/src/test/java/org/springframework/web/socket/server/support/OriginHandshakeInterceptorTests.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ public void originMatchAll() throws Exception {
114114
}
115115

116116
@Test
117-
public void sameOriginMatch() throws Exception {
117+
public void sameOriginMatchWithEmptyAllowedOrigins() throws Exception {
118118
Map<String, Object> attributes = new HashMap<String, Object>();
119119
WebSocketHandler wsHandler = Mockito.mock(WebSocketHandler.class);
120120
this.servletRequest.addHeader(HttpHeaders.ORIGIN, "http://mydomain2.com");
@@ -124,6 +124,17 @@ public void sameOriginMatch() throws Exception {
124124
assertNotEquals(servletResponse.getStatus(), HttpStatus.FORBIDDEN.value());
125125
}
126126

127+
@Test
128+
public void sameOriginMatchWithAllowedOrigins() throws Exception {
129+
Map<String, Object> attributes = new HashMap<String, Object>();
130+
WebSocketHandler wsHandler = Mockito.mock(WebSocketHandler.class);
131+
this.servletRequest.addHeader(HttpHeaders.ORIGIN, "http://mydomain2.com");
132+
this.servletRequest.setServerName("mydomain2.com");
133+
OriginHandshakeInterceptor interceptor = new OriginHandshakeInterceptor(Arrays.asList("http://mydomain1.com"));
134+
assertTrue(interceptor.beforeHandshake(request, response, wsHandler, attributes));
135+
assertNotEquals(servletResponse.getStatus(), HttpStatus.FORBIDDEN.value());
136+
}
137+
127138
@Test
128139
public void sameOriginNoMatch() throws Exception {
129140
Map<String, Object> attributes = new HashMap<String, Object>();

spring-websocket/src/test/java/org/springframework/web/socket/sockjs/support/SockJsServiceTests.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,13 +121,17 @@ public void handleInfoGetWithOrigin() throws Exception {
121121
assertEquals(",\"origins\":[\"*:*\"],\"cookie_needed\":true,\"websocket\":true}", body.substring(body.indexOf(',')));
122122

123123
this.service.setAllowedOrigins(Arrays.asList("http://mydomain1.com"));
124-
resetResponseAndHandleRequest("GET", "/echo/info", HttpStatus.FORBIDDEN);
124+
resetResponseAndHandleRequest("GET", "/echo/info", HttpStatus.OK);
125125

126126
this.service.setAllowedOrigins(Arrays.asList("http://mydomain1.com", "http://mydomain2.com", "http://mydomain3.com"));
127127
resetResponseAndHandleRequest("GET", "/echo/info", HttpStatus.OK);
128128

129129
this.service.setAllowedOrigins(Arrays.asList("*"));
130130
resetResponseAndHandleRequest("GET", "/echo/info", HttpStatus.OK);
131+
132+
this.servletRequest.setServerName("mydomain3.com");
133+
this.service.setAllowedOrigins(Arrays.asList("http://mydomain1.com"));
134+
resetResponseAndHandleRequest("GET", "/echo/info", HttpStatus.FORBIDDEN);
131135
}
132136

133137
@Test // SPR-11443
@@ -176,7 +180,8 @@ public void handleInfoOptionsWithOrigin() throws Exception {
176180
assertNotNull(this.service.getCorsConfiguration(this.servletRequest));
177181

178182
this.service.setAllowedOrigins(Arrays.asList("http://mydomain1.com"));
179-
resetResponseAndHandleRequest("OPTIONS", "/echo/info", HttpStatus.FORBIDDEN);
183+
resetResponseAndHandleRequest("OPTIONS", "/echo/info", HttpStatus.NO_CONTENT);
184+
assertNotNull(this.service.getCorsConfiguration(this.servletRequest));
180185

181186
this.service.setAllowedOrigins(Arrays.asList("http://mydomain1.com", "http://mydomain2.com", "http://mydomain3.com"));
182187
resetResponseAndHandleRequest("OPTIONS", "/echo/info", HttpStatus.NO_CONTENT);
@@ -185,6 +190,10 @@ public void handleInfoOptionsWithOrigin() throws Exception {
185190
this.service.setAllowedOrigins(Arrays.asList("*"));
186191
resetResponseAndHandleRequest("OPTIONS", "/echo/info", HttpStatus.NO_CONTENT);
187192
assertNotNull(this.service.getCorsConfiguration(this.servletRequest));
193+
194+
this.servletRequest.setServerName("mydomain3.com");
195+
this.service.setAllowedOrigins(Arrays.asList("http://mydomain1.com"));
196+
resetResponseAndHandleRequest("OPTIONS", "/echo/info", HttpStatus.FORBIDDEN);
188197
}
189198

190199
@Test // SPR-12283

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,18 @@ public void handleTransportRequestXhrAllowedOriginsNoMatch() throws Exception {
174174
assertEquals(403, this.servletResponse.getStatus());
175175
}
176176

177+
@Test // SPR-13464
178+
public void handleTransportRequestXhrSameOrigin() throws Exception {
179+
String sockJsPath = sessionUrlPrefix + "xhr";
180+
setRequest("POST", sockJsPrefix + sockJsPath);
181+
this.service.setAllowedOrigins(Arrays.asList("http://mydomain1.com"));
182+
this.servletRequest.addHeader(HttpHeaders.ORIGIN, "http://mydomain2.com");
183+
this.servletRequest.setServerName("mydomain2.com");
184+
this.service.handleRequest(this.request, this.response, sockJsPath, this.wsHandler);
185+
186+
assertEquals(200, this.servletResponse.getStatus());
187+
}
188+
177189
@Test
178190
public void handleTransportRequestXhrOptions() throws Exception {
179191
String sockJsPath = sessionUrlPrefix + "xhr";

0 commit comments

Comments
 (0)