diff -up ./java/org/apache/catalina/websocket/LocalStrings.properties.orig ./java/org/apache/catalina/websocket/LocalStrings.properties
--- ./java/org/apache/catalina/websocket/LocalStrings.properties.orig 2020-07-17 15:26:30.639711576 -0400
+++ ./java/org/apache/catalina/websocket/LocalStrings.properties 2020-07-17 15:26:39.051723026 -0400
@@ -14,6 +14,7 @@
# limitations under the License.
frame.eos=The end of the stream was reached before the expected number of payload bytes could be read
+frame.invalidLength=An invalid payload length was specified
frame.invalidUtf8=A sequence of bytes was received that did not represent valid UTF-8
frame.readFailed=Failed to read the first byte of the next WebSocket frame. The return value from the read was [{0}]
frame.readEos=The end of the stream was reached when trying to read the first byte of a new WebSocket frame
diff -up ./java/org/apache/catalina/websocket/WsFrame.java.orig ./java/org/apache/catalina/websocket/WsFrame.java
--- ./java/org/apache/catalina/websocket/WsFrame.java.orig 2020-07-17 15:26:44.341730227 -0400
+++ ./java/org/apache/catalina/websocket/WsFrame.java 2020-07-17 15:27:02.712755233 -0400
@@ -84,6 +84,12 @@ public class WsFrame {
blockingRead(processor, extended);
payloadLength = Conversions.byteArrayToLong(extended);
}
+ // The most significant bit of those 8 bytes is required to be zero
+ // (see RFC 6455, section 5.2). If the most significant bit is set,
+ // the resulting payload length will be negative so test for that.
+ if (payloadLength < 0) {
+ throw new IOException(sm.getString("frame.invalidLength"));
+ }
if (isControl()) {
if (payloadLength > 125) {
diff -up ./java/org/apache/tomcat/websocket/LocalStrings.properties.orig ./java/org/apache/tomcat/websocket/LocalStrings.properties
--- ./java/org/apache/tomcat/websocket/LocalStrings.properties.orig 2020-07-17 15:25:18.940613973 -0400
+++ ./java/org/apache/tomcat/websocket/LocalStrings.properties 2020-07-17 15:25:24.954622163 -0400
@@ -63,6 +63,7 @@ wsFrame.noContinuation=A new message was
wsFrame.notMasked=The client frame was not masked but all client frames must be masked
wsFrame.oneByteCloseCode=The client sent a close frame with a single byte payload which is not valid
wsFrame.partialHeaderComplete=WebSocket frame received. fin [{0}], rsv [{1}], OpCode [{2}], payload length [{3}]
+wsFrame.payloadMsbInvalid=An invalid WebSocket frame was received - the most significant bit of a 64-bit payload was illegally set
wsFrame.sessionClosed=The client data cannot be processed because the session has already been closed
wsFrame.textMessageTooBig=The decoded text message was too big for the output buffer and the endpoint does not support partial messages
wsFrame.wrongRsv=The client frame set the reserved bits to [{0}] for a message with opCode [{1}] which was not supported by this endpoint
diff -up ./java/org/apache/tomcat/websocket/WsFrameBase.java.orig ./java/org/apache/tomcat/websocket/WsFrameBase.java
--- ./java/org/apache/tomcat/websocket/WsFrameBase.java.orig 2020-07-17 15:25:04.371594139 -0400
+++ ./java/org/apache/tomcat/websocket/WsFrameBase.java 2020-07-17 15:25:14.292607645 -0400
@@ -260,6 +260,13 @@ public abstract class WsFrameBase {
readPos += 2;
} else if (payloadLength == 127) {
payloadLength = byteArrayToLong(inputBuffer, readPos, 8);
+ // The most significant bit of those 8 bytes is required to be zero
+ // (see RFC 6455, section 5.2). If the most significant bit is set,
+ // the resulting payload length will be negative so test for that.
+ if (payloadLength < 0) {
+ throw new WsIOException(
+ new CloseReason(CloseCodes.PROTOCOL_ERROR, sm.getString("wsFrame.payloadMsbInvalid")));
+ }
readPos += 8;
}
if (Util.isControl(opCode)) {
diff -up ./webapps/docs/changelog.xml.orig ./webapps/docs/changelog.xml
--- ./webapps/docs/changelog.xml.orig 2020-07-20 10:35:46.126504549 -0400
+++ ./webapps/docs/changelog.xml 2020-07-20 10:36:48.577591763 -0400
@@ -57,6 +57,16 @@
They eventually become mixed with the numbered issues. (I.e., numbered
issues do not "pop up" wrt. others).
-->
+<section name="Tomcat 7.0.76-15 (csutherl)">
+ <subsection name="WebSocket">
+ <changelog>
+ <fix>
+ <bug>64563</bug>: Add additional validation of payload length for
+ WebSocket messages. (markt)
+ </fix>
+ </changelog>
+ </subsection>
+</section>
<section name="Tomcat 7.0.76-14 (csutherl)">
<subsection name="Catalina">
<changelog>