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 da60768dff Expand the overhead protection to include another form of
misbehaviour
da60768dff is described below
commit da60768dff9a163c5580900ef4ff976402d15307
Author: Mark Thomas <[email protected]>
AuthorDate: Tue Oct 27 11:58:27 2026 +0000
Expand the overhead protection to include another form of misbehaviour
Note: This is NOT a DoS since there are plenty of ways legitimate requests
can generate just as much - if not significantly more - load. This is simply
taking the opportunity to detect an obviously misbehaving client.
---
.../coyote/http2/Http2AsyncUpgradeHandler.java | 1 +
.../apache/coyote/http2/Http2UpgradeHandler.java | 1 +
.../apache/coyote/http2/TestHttp2Section_6_5.java | 38 ++++++++++++++++++++++
webapps/docs/changelog.xml | 4 +++
4 files changed, 44 insertions(+)
diff --git a/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java
b/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java
index 8eaa6eeaad..bbd9360485 100644
--- a/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java
+++ b/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java
@@ -312,6 +312,7 @@ public class Http2AsyncUpgradeHandler extends
Http2UpgradeHandler {
if (!localSettings.ack()) {
// Ack was unexpected
log.warn(sm.getString("upgradeHandler.unexpectedAck",
connectionId, getIdAsString()));
+ increaseOverheadCount(FrameType.SETTINGS);
}
} else {
socketWrapper.write(BlockingMode.SEMI_BLOCK,
protocol.getWriteTimeout(), TimeUnit.MILLISECONDS, null,
diff --git a/java/org/apache/coyote/http2/Http2UpgradeHandler.java
b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
index 940c69389f..7358c81a5c 100644
--- a/java/org/apache/coyote/http2/Http2UpgradeHandler.java
+++ b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
@@ -1933,6 +1933,7 @@ class Http2UpgradeHandler extends AbstractStream
implements InternalHttpUpgradeH
if (!localSettings.ack()) {
// Ack was unexpected
log.warn(sm.getString("upgradeHandler.unexpectedAck",
connectionId, getIdAsString()));
+ increaseOverheadCount(FrameType.SETTINGS);
}
} else {
socketWrapper.getLock().lock();
diff --git a/test/org/apache/coyote/http2/TestHttp2Section_6_5.java
b/test/org/apache/coyote/http2/TestHttp2Section_6_5.java
index cba4b88958..5992a2f200 100644
--- a/test/org/apache/coyote/http2/TestHttp2Section_6_5.java
+++ b/test/org/apache/coyote/http2/TestHttp2Section_6_5.java
@@ -16,6 +16,8 @@
*/
package org.apache.coyote.http2;
+import java.net.SocketTimeoutException;
+
import org.junit.Assert;
import org.junit.Test;
@@ -37,6 +39,42 @@ public class TestHttp2Section_6_5 extends Http2TestBase {
}
+ @Test
+ public void testSettingsFrameEmptyAckFlood() throws Exception {
+ // HTTP2 upgrade
+ http2Connect();
+
+ sendSimpleGetRequest(3);
+ readSimpleGetResponse();
+ output.clearTrace();
+
+ // Unsolicited, empty SETTINGS ACK frames
+ for (int i = 0; i < 100; i++) {
+ sendSettings(0, true);
+ }
+
+ sendSimpleGetRequest(5);
+
+ /*
+ * Expect the server to close the connection with ENHANCE_YOUR_CALM.
The response to the second GET request may
+ * or may not be written first so read frames until the GOAWAY arrives.
+ */
+ s.setSoTimeout(5000);
+ String expected = "0-Goaway-[";
+ try {
+ while (!output.getTrace().contains(expected)) {
+ parser.readFrame();
+ }
+ } catch (SocketTimeoutException ste) {
+ Assert.fail("No GOAWAY received after 100 empty SETTINGS ACK
frames. Frames seen: [" + output.getTrace() +
+ "]");
+ }
+
+ String trace = output.getTrace();
+ Assert.assertTrue(trace, trace.contains("]-[" +
Http2Error.ENHANCE_YOUR_CALM.getCode() + "]-["));
+ }
+
+
@Test
public void testSettingsFrameNonZeroStream() throws Exception {
// HTTP2 upgrade
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index d31b1b6afc..c8d884d3dd 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -443,6 +443,10 @@
<code>org.apache.tomcat.util.http.parser.StandardAcceptLanguageParser</code>
to <code>true</code>. (remm)
</fix>
+ <fix>
+ Detect and disconnect a mis-behaving HTTP/2 client that sends large
+ numbers of unexpected settings acknowledgement frames. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Jasper">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]