Browse Source

Handle invalid STOMP content-length header value

After this change if a content-length header is provided but is less
than 0 or cannot be parsed as a number, it is ignored and the body
is read sequentially, i.e. until we reach a null byte terminator.

This provides better protection against clients that may set the
content-length header in error.

Issue: SPR-11528
pull/448/merge
Rossen Stoyanchev 11 years ago
parent
commit
13af188bdc
  1. 17
      spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompDecoder.java
  2. 32
      spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/StompCodecTests.java

17
spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompDecoder.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -28,6 +28,7 @@ import org.springframework.messaging.simp.SimpMessageType; @@ -28,6 +28,7 @@ import org.springframework.messaging.simp.SimpMessageType;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
/**
* Decodes STOMP frames from a {@link ByteBuffer}. If the buffer does not contain
@ -151,9 +152,17 @@ public class StompDecoder { @@ -151,9 +152,17 @@ public class StompDecoder {
}
private byte[] readPayload(ByteBuffer buffer, MultiValueMap<String, String> headers) {
String contentLengthString = headers.getFirst("content-length");
if (contentLengthString != null) {
int contentLength = Integer.valueOf(contentLengthString);
Integer contentLength = null;
if (headers.containsKey("content-length")) {
String rawContentLength = headers.getFirst("content-length");
try {
contentLength = Integer.valueOf(rawContentLength);
}
catch (NumberFormatException ex) {
logger.warn("Ignoring invalid content-length header value: '" + rawContentLength + "'");
}
}
if (contentLength != null && contentLength >= 0) {
if (buffer.remaining() > contentLength) {
byte[] payload = new byte[contentLength];
buffer.get(payload);

32
spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/StompCodecTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -107,6 +107,36 @@ public class StompCodecTests { @@ -107,6 +107,36 @@ public class StompCodecTests {
assertEquals("The body of the message", bodyText);
}
// SPR-11528
@Test
public void decodeFrameWithInvalidContentLength() {
Message<byte[]> frame = decode("SEND\ncontent-length:-1\n\nThe body of the message\0");
StompHeaderAccessor headers = StompHeaderAccessor.wrap(frame);
assertEquals(StompCommand.SEND, headers.getCommand());
assertEquals(1, headers.toStompHeaderMap().size());
assertEquals(Integer.valueOf(-1), headers.getContentLength());
String bodyText = new String(frame.getPayload());
assertEquals("The body of the message", bodyText);
}
@Test
public void decodeFrameWithContentLengthZero() {
Message<byte[]> frame = decode("SEND\ncontent-length:0\n\n\0");
StompHeaderAccessor headers = StompHeaderAccessor.wrap(frame);
assertEquals(StompCommand.SEND, headers.getCommand());
assertEquals(1, headers.toStompHeaderMap().size());
assertEquals(Integer.valueOf(0), headers.getContentLength());
String bodyText = new String(frame.getPayload());
assertEquals("", bodyText);
}
@Test
public void decodeFrameWithNullOctectsInTheBody() {
Message<byte[]> frame = decode("SEND\ncontent-length:23\n\nThe b\0dy \0f the message\0");

Loading…
Cancel
Save