This is an automated email from the ASF dual-hosted git repository.

markt-asf pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/10.1.x by this push:
     new facae27db3 Expand the overhead protection to include another form of 
misbehaviour
facae27db3 is described below

commit facae27db36383dd4774afea7cdaabbb866c1dd7
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 e767226e4c..0ac17ce723 100644
--- a/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java
+++ b/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java
@@ -313,6 +313,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 77a53f6ca2..cbad728eaf 100644
--- a/java/org/apache/coyote/http2/Http2UpgradeHandler.java
+++ b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
@@ -2015,6 +2015,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 f826914013..09caabec34 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 d783770d87..371c60aad1 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -439,6 +439,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]

Reply via email to