diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/TransportHandlingSockJsService.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/TransportHandlingSockJsService.java index 0c98eeb1525..dd44e533cb9 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/TransportHandlingSockJsService.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/TransportHandlingSockJsService.java @@ -17,6 +17,7 @@ package org.springframework.web.socket.sockjs.transport; import java.io.IOException; +import java.net.InetSocketAddress; import java.security.Principal; import java.time.Duration; import java.util.ArrayList; @@ -308,7 +309,20 @@ public class TransportHandlingSockJsService extends AbstractSockJsService implem Principal currentPrincipal = request.getPrincipal(); if (!principal.equals(currentPrincipal) && (currentPrincipal == null || !principal.getName().equals(currentPrincipal.getName()))) { - logger.debug("The user for the session does not match the user for the request."); + logger.debug("The user for the session and the request do not match¶."); + response.setStatusCode(HttpStatus.NOT_FOUND); + return; + } + } + else { + if (request.getPrincipal() != null) { + logger.debug("The request has a user, but the session does not."); + response.setStatusCode(HttpStatus.NOT_FOUND); + return; + } + InetSocketAddress remoteAddress = session.getRemoteAddress(); + if (remoteAddress != null && !remoteAddress.equals(request.getRemoteAddress())) { + logger.debug("The remote address for the session and the request do not match."); response.setStatusCode(HttpStatus.NOT_FOUND); return; } diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/sockjs/transport/handler/DefaultSockJsServiceTests.java b/spring-websocket/src/test/java/org/springframework/web/socket/sockjs/transport/handler/DefaultSockJsServiceTests.java index d7ed52c78d5..70f62314ce6 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/sockjs/transport/handler/DefaultSockJsServiceTests.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/sockjs/transport/handler/DefaultSockJsServiceTests.java @@ -16,6 +16,7 @@ package org.springframework.web.socket.sockjs.transport.handler; +import java.net.InetSocketAddress; import java.time.Duration; import java.util.Arrays; import java.util.Collections; @@ -280,6 +281,29 @@ class DefaultSockJsServiceTests extends AbstractHttpRequestTests { verifyNoMoreInteractions(this.xhrSendHandler); } + @Test + void handleTransportRequestXhrSendWithDifferentRemoteAddress() { + String sockJsPath = sessionUrlPrefix + "xhr"; + setRequest("POST", sockJsPrefix + sockJsPath); + this.service.handleRequest(this.request, this.response, sockJsPath, this.wsHandler); + + // session created + assertThat(this.servletResponse.getStatus()).isEqualTo(200); + verify(this.xhrHandler).handleRequest(this.request, this.response, this.wsHandler, this.session); + + this.session.setRemoteAddress(new InetSocketAddress("127.0.0.1:8080", 8080)); + this.servletRequest.setRemoteAddr("127.0.0.1:9090"); + + resetResponse(); + reset(this.xhrSendHandler); + sockJsPath = sessionUrlPrefix + "xhr_send"; + setRequest("POST", sockJsPrefix + sockJsPath); + this.service.handleRequest(this.request, this.response, sockJsPath, this.wsHandler); + + assertThat(this.servletResponse.getStatus()).isEqualTo(404); + verifyNoMoreInteractions(this.xhrSendHandler); + } + @Test void handleTransportRequestWebsocket() { TransportHandlingSockJsService wsService = new TransportHandlingSockJsService(