Blob Blame History Raw
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>