Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reject "%2F" as an invalid sequence in simp messaging usernames #23836

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -31,7 +31,7 @@
import org.springframework.messaging.support.MessageHeaderInitializer;
import org.springframework.messaging.support.NativeMessageHeaderAccessor;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.util.Base64Utils;

/**
* An implementation of
Expand Down Expand Up @@ -224,7 +224,8 @@ public void convertAndSendToUser(String user, String destination, Object payload
throws MessagingException {

Assert.notNull(user, "User must not be null");
user = StringUtils.replace(user, "/", "%2F");
if (user.startsWith("B64:") || user.contains("/"))
user = "B64:" + Base64Utils.encodeToUrlSafeString(user.getBytes());
destination = destination.startsWith("/") ? destination : "/" + destination;
super.convertAndSend(this.destinationPrefix + user + destination, payload, headers, postProcessor);
}
Expand Down
Expand Up @@ -31,7 +31,7 @@
import org.springframework.messaging.simp.SimpMessageType;
import org.springframework.util.Assert;
import org.springframework.util.PathMatcher;
import org.springframework.util.StringUtils;
import org.springframework.util.Base64Utils;

/**
* A default implementation of {@code UserDestinationResolver} that relies
Expand Down Expand Up @@ -214,7 +214,8 @@ private ParseResult parseMessage(MessageHeaders headers, String sourceDest) {
String actualDest = sourceDest.substring(userEnd);
String subscribeDest = this.prefix.substring(0, prefixEnd - 1) + actualDest;
String userName = sourceDest.substring(prefixEnd, userEnd);
userName = StringUtils.replace(userName, "%2F", "/");
if (userName.startsWith("B64:"))
userName = new String(Base64Utils.decodeFromUrlSafeString(userName.split("B64:")[1]));

String sessionId = SimpMessageHeaderAccessor.getSessionId(headers);
Set<String> sessionIds;
Expand Down
Expand Up @@ -83,7 +83,21 @@ public void convertAndSendToUserWithEncoding() {
MessageHeaderAccessor.getAccessor(messages.get(0), SimpMessageHeaderAccessor.class);

assertThat(headerAccessor).isNotNull();
assertThat(headerAccessor.getDestination()).isEqualTo("/user/https:%2F%2Fjoe.openid.example.org%2F/queue/foo");
assertThat(headerAccessor.getDestination()).isEqualTo("/user/B64:aHR0cHM6Ly9qb2Uub3BlbmlkLmV4YW1wbGUub3JnLw==/queue/foo");
}

@Test
public void convertAndSendToUserWithEncodingOfPercentTwoEff() {
this.messagingTemplate.convertAndSendToUser("https%3A%2F%2Fjoe.openid.example.org%2F|911276df-8a4f-4fda-986a-0713aba85b5e", "/queue/foo", "data");
List<Message<byte[]>> messages = this.messageChannel.getMessages();

assertThat(messages.size()).isEqualTo(1);

SimpMessageHeaderAccessor headerAccessor =
MessageHeaderAccessor.getAccessor(messages.get(0), SimpMessageHeaderAccessor.class);

assertThat(headerAccessor).isNotNull();
assertThat(headerAccessor.getDestination()).isEqualTo("/user/https%3A%2F%2Fjoe.openid.example.org%2F|911276df-8a4f-4fda-986a-0713aba85b5e/queue/foo");
}

@Test
Expand Down
Expand Up @@ -27,6 +27,7 @@
import org.springframework.messaging.simp.TestPrincipal;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.util.StringUtils;
import org.springframework.util.Base64Utils;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
Expand Down Expand Up @@ -180,7 +181,24 @@ public void handleMessageEncodedUserName() {
simpUser.addSessions(new TestSimpSession("openid123"));
given(this.registry.getUser(userName)).willReturn(simpUser);

String destination = "/user/" + StringUtils.replace(userName, "/", "%2F") + "/queue/foo";
String destination = "/user/B64:" + Base64Utils.encodeToUrlSafeString(userName.getBytes()) + "/queue/foo";

Message<?> message = createMessage(SimpMessageType.MESSAGE, new TestPrincipal("joe"), null, destination);
UserDestinationResult actual = this.resolver.resolveDestination(message);

assertThat(actual.getTargetDestinations().size()).isEqualTo(1);
assertThat(actual.getTargetDestinations().iterator().next()).isEqualTo("/queue/foo-useropenid123");
}

@Test
public void handleMessageEncodedUserNameWithPercentTwoEff() {
String userName = "https%3A%2F%2Fjoe.openid.example.org%2F|911276df-8a4f-4fda-986a-0713aba85b5e";

TestSimpUser simpUser = new TestSimpUser(userName);
simpUser.addSessions(new TestSimpSession("openid123"));
given(this.registry.getUser(userName)).willReturn(simpUser);

String destination = "/user/" + userName + "/queue/foo";

Message<?> message = createMessage(SimpMessageType.MESSAGE, new TestPrincipal("joe"), null, destination);
UserDestinationResult actual = this.resolver.resolveDestination(message);
Expand Down