This is an automated email from the ASF dual-hosted git repository.
markt-asf pushed a commit to branch 11.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/11.0.x by this push:
new d6c37178b1 Improve HTTP/2 frame payload length validation
d6c37178b1 is described below
commit d6c37178b1136caeb13a81eebe8d97ee999b7edd
Author: Mark Thomas <[email protected]>
AuthorDate: Wed Jun 10 16:30:50 2026 +0100
Improve HTTP/2 frame payload length validation
---
java/org/apache/coyote/http2/Http2Parser.java | 16 +++++++++++++
.../apache/coyote/http2/LocalStrings.properties | 1 +
.../apache/coyote/http2/TestHttp2Section_4_2.java | 27 +++++++++++++++++++++-
webapps/docs/changelog.xml | 4 ++++
4 files changed, 47 insertions(+), 1 deletion(-)
diff --git a/java/org/apache/coyote/http2/Http2Parser.java
b/java/org/apache/coyote/http2/Http2Parser.java
index 39d4ef310a..938a802b98 100644
--- a/java/org/apache/coyote/http2/Http2Parser.java
+++ b/java/org/apache/coyote/http2/Http2Parser.java
@@ -141,6 +141,14 @@ class Http2Parser {
int dataLength;
if (Flags.hasPadding(flags)) {
+
+ // Frame is too small to contain mandatory frame data (for the
given flags)
+ if (payloadSize == 0) {
+ throw new
ConnectionException(sm.getString("http2Parser.processFrame.insufficientPayload",connectionId,
+ Integer.toString(streamId),
Integer.toString(FrameType.DATA.getId()),
+ Integer.toString(flags),
Integer.toString(payloadSize)), Http2Error.FRAME_SIZE_ERROR);
+ }
+
if (buffer == null) {
byte[] b = new byte[1];
input.fill(true, b);
@@ -247,6 +255,14 @@ class Http2Parser {
if (priority) {
optionalLen += 5;
}
+
+ // Frame is too small to contain mandatory frame data (for the given
flags)
+ if (payloadSize < optionalLen) {
+ throw new
ConnectionException(sm.getString("http2Parser.processFrame.insufficientPayload",connectionId,
+ Integer.toString(streamId),
Integer.toString(FrameType.HEADERS.getId()),
+ Integer.toString(flags), Integer.toString(payloadSize)),
Http2Error.FRAME_SIZE_ERROR);
+ }
+
if (optionalLen > 0) {
byte[] optional = new byte[optionalLen];
if (buffer == null) {
diff --git a/java/org/apache/coyote/http2/LocalStrings.properties
b/java/org/apache/coyote/http2/LocalStrings.properties
index ded1e4794e..8837f20c6f 100644
--- a/java/org/apache/coyote/http2/LocalStrings.properties
+++ b/java/org/apache/coyote/http2/LocalStrings.properties
@@ -75,6 +75,7 @@ http2Parser.payloadTooBig=The payload is [{0}] bytes long but
the maximum frame
http2Parser.preface.invalid=Invalid connection preface presented
http2Parser.preface.io=Unable to read connection preface
http2Parser.processFrame=Connection [{0}], Stream [{1}], Frame type [{2}],
Flags [{3}], Payload size [{4}]
+http2Parser.processFrame.insufficientPayload=Connection [{0}], Stream [{1}],
Frame type [{2}] with Flags [{3}] requires a larger payload than [{4}]
http2Parser.processFrame.tooMuchPadding=Connection [{0}], Stream [{1}], The
padding length [{2}] was too big for the payload [{3}]
http2Parser.processFrame.unexpectedType=Expected frame type [{0}] but received
frame type [{1}]
http2Parser.processFrameContinuation.notExpected=Connection [{0}],
Continuation frame received for stream [{1}] when no headers were in progress
diff --git a/test/org/apache/coyote/http2/TestHttp2Section_4_2.java
b/test/org/apache/coyote/http2/TestHttp2Section_4_2.java
index d73a2495a7..3745fbe07e 100644
--- a/test/org/apache/coyote/http2/TestHttp2Section_4_2.java
+++ b/test/org/apache/coyote/http2/TestHttp2Section_4_2.java
@@ -81,7 +81,7 @@ public class TestHttp2Section_4_2 extends Http2TestBase {
@Test
- public void testFrameTypeLimitsTooSmall() throws Exception {
+ public void testFrameTypeLimitsTooSmallPing() throws Exception {
// HTTP2 upgrade
http2Connect();
@@ -103,6 +103,31 @@ public class TestHttp2Section_4_2 extends Http2TestBase {
}
+ @Test
+ public void testFrameTypeLimitsTooSmallHeaders() throws Exception {
+ // HTTP2 upgrade
+ http2Connect();
+
+ // Too small headers
+ byte[] headers = new byte[9];
+
+ // Header
+ // Length 0
+ // Type
+ headers[3] = FrameType.HEADERS.getIdByte();
+ // Set flags: End headers 0x04, Priority 0x20
+ headers[4] = 0x24;
+ // Stream 3
+ ByteUtil.set31Bits(headers, 5, 3);
+ // Empty payload
+
+ os.write(headers);
+ os.flush();
+
+ handleGoAwayResponse(1, Http2Error.FRAME_SIZE_ERROR);
+ }
+
+
@Test
public void testFrameTypeLimitsStream() throws Exception {
// HTTP2 upgrade
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 0c50cdf434..4b9a3eb523 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -349,6 +349,10 @@
<code>@STRENGTH</code> was encountered, ignoring any subsequent
expressions. (markt)
</fix>
+ <fix>
+ Handle the case where the HTTP/2 payload length is insufficient for the
+ mandatory data required by the flags set in the header. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Jasper">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]