diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompBrokerRelayMessageHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompBrokerRelayMessageHandler.java index cab92b50ac8..6c5aeb5f17e 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompBrokerRelayMessageHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompBrokerRelayMessageHandler.java @@ -456,10 +456,7 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler accessor.setLogin(this.systemLogin); accessor.setPasscode(this.systemPasscode); accessor.setHeartbeat(this.systemHeartbeatSendInterval, this.systemHeartbeatReceiveInterval); - String virtualHost = getVirtualHost(); - if (virtualHost != null) { - accessor.setHost(virtualHost); - } + accessor.setHost(getVirtualHost() != null ? getVirtualHost() : getRelayHost()); accessor.setSessionId(SYSTEM_SESSION_ID); if (logger.isDebugEnabled()) { logger.debug("Forwarding " + accessor.getShortLogMessage(EMPTY_PAYLOAD)); @@ -582,9 +579,7 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler stompHeaderAccessor = (stompHeaderAccessor.isMutable() ? stompHeaderAccessor : StompHeaderAccessor.wrap(message)); stompHeaderAccessor.setLogin(this.clientLogin); stompHeaderAccessor.setPasscode(this.clientPasscode); - if (getVirtualHost() != null) { - stompHeaderAccessor.setHost(getVirtualHost()); - } + stompHeaderAccessor.setHost(getVirtualHost() != null ? getVirtualHost() : getRelayHost()); RelayConnectionHandler handler = new RelayConnectionHandler(sessionId, stompHeaderAccessor); this.connectionHandlers.put(sessionId, handler); this.stats.incrementConnectCount(); diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/user/UserDestinationMessageHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/user/UserDestinationMessageHandler.java index c220f492705..f0122d5df9a 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/user/UserDestinationMessageHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/user/UserDestinationMessageHandler.java @@ -38,6 +38,7 @@ import org.springframework.messaging.simp.SimpMessageHeaderAccessor; import org.springframework.messaging.simp.SimpMessageType; import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.messaging.simp.broker.OrderedMessageChannelDecorator; +import org.springframework.messaging.simp.stomp.StompBrokerRelayMessageHandler; import org.springframework.messaging.support.MessageBuilder; import org.springframework.messaging.support.MessageHeaderAccessor; import org.springframework.messaging.support.MessageHeaderInitializer; @@ -333,8 +334,9 @@ public class UserDestinationMessageHandler implements MessageHandler, SmartLifec SimpMessageHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, SimpMessageHeaderAccessor.class); Assert.state(accessor != null, "No SimpMessageHeaderAccessor"); - if (accessor.getSessionId() == null) { - // Our own broadcast + if (accessor.getSessionId() == null || + !accessor.getSessionId().equals(StompBrokerRelayMessageHandler.SYSTEM_SESSION_ID)) { + // Our own or not a broadcast return null; } destination = accessor.getFirstNativeHeader(SimpMessageHeaderAccessor.ORIGINAL_DESTINATION); diff --git a/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/StompBrokerRelayMessageHandlerTests.java b/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/StompBrokerRelayMessageHandlerTests.java index 0c5729ffe5c..eb712b655cf 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/StompBrokerRelayMessageHandlerTests.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/StompBrokerRelayMessageHandlerTests.java @@ -245,7 +245,12 @@ class StompBrokerRelayMessageHandlerTests { ArgumentCaptor captor = ArgumentCaptor.forClass(Message.class); verify(handler).handleMessage(captor.capture()); - assertThat(captor.getValue()).isSameAs(message); + + Message actual = captor.getValue(); + assertThat(actual).isSameAs(message); + + accessor = StompHeaderAccessor.getAccessor(actual, StompHeaderAccessor.class); + assertThat(accessor.getSessionId()).isEqualTo(StompBrokerRelayMessageHandler.SYSTEM_SESSION_ID); } @Test diff --git a/spring-messaging/src/test/java/org/springframework/messaging/simp/user/UserDestinationMessageHandlerTests.java b/spring-messaging/src/test/java/org/springframework/messaging/simp/user/UserDestinationMessageHandlerTests.java index 937694fdf3d..cb6f5b03cc3 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/simp/user/UserDestinationMessageHandlerTests.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/simp/user/UserDestinationMessageHandlerTests.java @@ -30,6 +30,7 @@ import org.springframework.messaging.StubMessageChannel; import org.springframework.messaging.SubscribableChannel; import org.springframework.messaging.simp.SimpMessageHeaderAccessor; import org.springframework.messaging.simp.SimpMessageType; +import org.springframework.messaging.simp.stomp.StompBrokerRelayMessageHandler; import org.springframework.messaging.simp.stomp.StompCommand; import org.springframework.messaging.simp.stomp.StompHeaderAccessor; import org.springframework.messaging.support.MessageBuilder; @@ -151,7 +152,7 @@ class UserDestinationMessageHandlerTests { given(this.brokerChannel.send(Mockito.any(Message.class))).willReturn(true); StompHeaderAccessor accessor = StompHeaderAccessor.create(StompCommand.MESSAGE); - accessor.setSessionId("system123"); + accessor.setSessionId(StompBrokerRelayMessageHandler.SYSTEM_SESSION_ID); accessor.setDestination("/topic/unresolved"); accessor.setNativeHeader(ORIGINAL_DESTINATION, "/user/joe/queue/foo"); accessor.setNativeHeader("customHeader", "customHeaderValue"); @@ -175,7 +176,7 @@ class UserDestinationMessageHandlerTests { given(this.brokerChannel.send(Mockito.any(Message.class))).willReturn(true); StompHeaderAccessor accessor = StompHeaderAccessor.create(StompCommand.MESSAGE); - accessor.setSessionId("system123"); + accessor.setSessionId(StompBrokerRelayMessageHandler.SYSTEM_SESSION_ID); accessor.setDestination("/topic/unresolved"); accessor.setNativeHeader(ORIGINAL_DESTINATION, "/user/joe/queue/foo"); accessor.setLeaveMutable(true); 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(