VYPR
High severityNVD Advisory· Published Jul 10, 2025· Updated Nov 4, 2025

Apache Tomcat: DoS via excessive h2 streams at connection start

CVE-2025-53506

Description

Uncontrolled Resource Consumption vulnerability in Apache Tomcat if an HTTP/2 client did not acknowledge the initial settings frame that reduces the maximum permitted concurrent streams.

This issue affects Apache Tomcat: from 11.0.0-M1 through 11.0.8, from 10.1.0-M1 through 10.1.42, from 9.0.0.M1 through 9.0.106. The following versions were EOL at the time the CVE was created but are known to be affected: 8.5.0 through 8.5.100. Other EOL versions may also be affected.

Users are recommended to upgrade to version 11.0.9, 10.1.43 or 9.0.107, which fix the issue.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Apache Tomcat HTTP/2 settings not enforced until ACK, allowing resource exhaustion by unacknowledged streams.

What the vulnerability is: The CVE-2025-53506 describes an Uncontrolled Resource Consumption vulnerability in Apache Tomcat's HTTP/2 implementation. When an HTTP/2 client does not acknowledge the initial SETTINGS frame that reduces the maximum permitted concurrent streams, the server does not enforce the lower limit. This allows the client to open more streams than intended, leading to resource exhaustion [1].

How it is exploited: An attacker can establish an HTTP/2 connection without sending the required ACK for the SETTINGS frame. By ignoring the initial stream limit, the attacker can open a large number of concurrent streams, consuming server resources such as memory and CPU. The attack requires only network access to the Tomcat server and no authentication [1].

Impact: Successful exploitation can cause denial of service (DoS) by exhausting server resources, potentially degrading performance or crashing the server. This affects availability and can impact other services running on the same host.

Mitigation: Apache has released fixes in versions 11.0.9, 10.1.43, and 9.0.107. Users should upgrade immediately. The fix enforces the initial stream limits immediately upon receiving the SETTINGS frame, rather than waiting for an ACK [2][3][4]. EOL versions (e.g., 8.5.x) are also affected but no patches are provided; upgrading to a supported version is recommended [1].

AI Insight generated on May 19, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.apache.tomcat:tomcat-coyoteMaven
>= 11.0.0-M1, < 11.0.911.0.9
org.apache.tomcat:tomcat-coyoteMaven
>= 10.1.0-M1, < 10.1.4310.1.43
org.apache.tomcat:tomcat-coyoteMaven
>= 9.0.0.M1, < 9.0.1079.0.107
org.apache.tomcat:tomcat-coyoteMaven
>= 8.5.0, <= 8.5.100
org.apache.tomcat.embed:tomcat-embed-coreMaven
>= 8.5.0, <= 8.5.100
org.apache.tomcat.embed:tomcat-embed-coreMaven
>= 9.0.0.M1, < 9.0.1079.0.107
org.apache.tomcat.embed:tomcat-embed-coreMaven
>= 10.1.0-M1, < 10.1.4310.1.43
org.apache.tomcat.embed:tomcat-embed-coreMaven
>= 11.0.0-M1, < 11.0.911.0.9

Affected products

2
  • Apache/Tomcatllm-fuzzy
    Range: >=8.5.0, <=8.5.100 || >=9.0.0-M1, <=9.0.106 || >=10.1.0-M1, <=10.1.42 || >=11.0.0-M1, <=11.0.8
  • Apache Software Foundation/Apache Tomcatv5
    Range: 11.0.0-M1

Patches

3
434772930f36

Apply the initial HTTP/2 connection limits earlier.

https://github.com/apache/tomcatMark ThomasJul 1, 2025via ghsa
4 files changed · +31 5
  • java/org/apache/coyote/http2/ConnectionSettingsBase.java+17 2 modified
    @@ -66,6 +66,11 @@ abstract class ConnectionSettingsBase<T extends Throwable> {
     
     
         final void set(Setting setting, long value) throws T {
    +        set(setting,  value, false);
    +    }
    +
    +
    +    final void set(Setting setting, long value, boolean force) throws T {
             if (log.isTraceEnabled()) {
                 log.trace(sm.getString("connectionSettings.debug", connectionId, getEndpointName(), setting,
                         Long.toString(value)));
    @@ -102,11 +107,21 @@ final void set(Setting setting, long value) throws T {
                     return;
             }
     
    -        set(setting, Long.valueOf(value));
    +        set(setting, Long.valueOf(value), force);
         }
     
     
    -    synchronized void set(Setting setting, Long value) {
    +    /**
    +     * Specify a new value for setting with the option to force the change to take effect immediately rather than
    +     * waiting until an {@code ACK} is received.
    +     *
    +     * @param setting The setting to update
    +     * @param value   The new value for the setting
    +     * @param force   {@code false} if an {@code ACK} must be received before the setting takes effect or {@code true}
    +     *                    if the setting to take effect immediately. Even if the setting takes effect immediately, it
    +     *                    will still be included in the next {@code SETTINGS} frame and an {@code ACK} will be expected.
    +     */
    +    synchronized void set(Setting setting, Long value, boolean force) {
             current.put(setting, value);
         }
     
    
  • java/org/apache/coyote/http2/ConnectionSettingsLocal.java+4 1 modified
    @@ -40,12 +40,15 @@ class ConnectionSettingsLocal extends ConnectionSettingsBase<IllegalArgumentExce
     
     
         @Override
    -    final synchronized void set(Setting setting, Long value) {
    +    final synchronized void set(Setting setting, Long value, boolean force) {
             checkSend();
             if (current.get(setting).longValue() == value.longValue()) {
                 pending.remove(setting);
             } else {
                 pending.put(setting, value);
    +            if (force) {
    +                current.put(setting, value);
    +            }
             }
         }
     
    
  • java/org/apache/coyote/http2/Http2UpgradeHandler.java+6 2 modified
    @@ -161,8 +161,12 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
             remoteSettings = new ConnectionSettingsRemote(connectionId);
             localSettings = new ConnectionSettingsLocal(connectionId);
     
    -        localSettings.set(Setting.MAX_CONCURRENT_STREAMS, protocol.getMaxConcurrentStreams());
    -        localSettings.set(Setting.INITIAL_WINDOW_SIZE, protocol.getInitialWindowSize());
    +        /*
    +         * Force set these initial limits. A well-behaved client should ACK the settings and adhere to them before it
    +         * reaches the limits anyway.
    +         */
    +        localSettings.set(Setting.MAX_CONCURRENT_STREAMS, protocol.getMaxConcurrentStreams(), true);
    +        localSettings.set(Setting.INITIAL_WINDOW_SIZE, protocol.getInitialWindowSize(), true);
     
             pingManager.initiateDisabled = protocol.getInitiatePingDisabled();
     
    
  • webapps/docs/changelog.xml+4 0 modified
    @@ -160,6 +160,10 @@
             application tries to use CLIENT-CERT with either HTTP/2 or a JSSE
             implementation of TLS 1.3. (markt)
           </fix>
    +      <fix>
    +        When setting the initial HTTP/2 connection limit, apply those limits
    +        earlier. (markt)
    +      </fix>
         </changelog>
       </subsection>
       <subsection name="Jasper">
    
2aa6261276eb

Apply the initial HTTP/2 connection limits earlier.

https://github.com/apache/tomcatMark ThomasJul 1, 2025via ghsa
4 files changed · +31 5
  • java/org/apache/coyote/http2/ConnectionSettingsBase.java+17 2 modified
    @@ -66,6 +66,11 @@ abstract class ConnectionSettingsBase<T extends Throwable> {
     
     
         final void set(Setting setting, long value) throws T {
    +        set(setting,  value, false);
    +    }
    +
    +
    +    final void set(Setting setting, long value, boolean force) throws T {
             if (log.isTraceEnabled()) {
                 log.trace(sm.getString("connectionSettings.debug", connectionId, getEndpointName(), setting,
                         Long.toString(value)));
    @@ -102,11 +107,21 @@ final void set(Setting setting, long value) throws T {
                     return;
             }
     
    -        set(setting, Long.valueOf(value));
    +        set(setting, Long.valueOf(value), force);
         }
     
     
    -    synchronized void set(Setting setting, Long value) {
    +    /**
    +     * Specify a new value for setting with the option to force the change to take effect immediately rather than
    +     * waiting until an {@code ACK} is received.
    +     *
    +     * @param setting The setting to update
    +     * @param value   The new value for the setting
    +     * @param force   {@code false} if an {@code ACK} must be received before the setting takes effect or {@code true}
    +     *                    if the setting to take effect immediately. Even if the setting takes effect immediately, it
    +     *                    will still be included in the next {@code SETTINGS} frame and an {@code ACK} will be expected.
    +     */
    +    synchronized void set(Setting setting, Long value, boolean force) {
             current.put(setting, value);
         }
     
    
  • java/org/apache/coyote/http2/ConnectionSettingsLocal.java+4 1 modified
    @@ -40,12 +40,15 @@ class ConnectionSettingsLocal extends ConnectionSettingsBase<IllegalArgumentExce
     
     
         @Override
    -    final synchronized void set(Setting setting, Long value) {
    +    final synchronized void set(Setting setting, Long value, boolean force) {
             checkSend();
             if (current.get(setting).longValue() == value.longValue()) {
                 pending.remove(setting);
             } else {
                 pending.put(setting, value);
    +            if (force) {
    +                current.put(setting, value);
    +            }
             }
         }
     
    
  • java/org/apache/coyote/http2/Http2UpgradeHandler.java+6 2 modified
    @@ -164,8 +164,12 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
             remoteSettings = new ConnectionSettingsRemote(connectionId);
             localSettings = new ConnectionSettingsLocal(connectionId);
     
    -        localSettings.set(Setting.MAX_CONCURRENT_STREAMS, protocol.getMaxConcurrentStreams());
    -        localSettings.set(Setting.INITIAL_WINDOW_SIZE, protocol.getInitialWindowSize());
    +        /*
    +         * Force set these initial limits. A well-behaved client should ACK the settings and adhere to them before it
    +         * reaches the limits anyway.
    +         */
    +        localSettings.set(Setting.MAX_CONCURRENT_STREAMS, protocol.getMaxConcurrentStreams(), true);
    +        localSettings.set(Setting.INITIAL_WINDOW_SIZE, protocol.getInitialWindowSize(), true);
     
             pingManager.initiateDisabled = protocol.getInitiatePingDisabled();
     
    
  • webapps/docs/changelog.xml+4 0 modified
    @@ -157,6 +157,10 @@
             application tries to use CLIENT-CERT with either HTTP/2 or a JSSE
             implementation of TLS 1.3. (markt)
           </fix>
    +      <fix>
    +        When setting the initial HTTP/2 connection limit, apply those limits
    +        earlier. (markt)
    +      </fix>
         </changelog>
       </subsection>
       <subsection name="Jasper">
    
be8f330f83ce

Apply the initial HTTP/2 connection limits earlier.

https://github.com/apache/tomcatMark ThomasJul 1, 2025via ghsa
4 files changed · +31 5
  • java/org/apache/coyote/http2/ConnectionSettingsBase.java+17 2 modified
    @@ -65,6 +65,11 @@ abstract class ConnectionSettingsBase<T extends Throwable> {
     
     
         final void set(Setting setting, long value) throws T {
    +        set(setting,  value, false);
    +    }
    +
    +
    +    final void set(Setting setting, long value, boolean force) throws T {
             if (log.isTraceEnabled()) {
                 log.trace(sm.getString("connectionSettings.debug", connectionId, getEndpointName(), setting,
                         Long.toString(value)));
    @@ -90,11 +95,21 @@ final void set(Setting setting, long value) throws T {
                 }
             }
     
    -        set(setting, Long.valueOf(value));
    +        set(setting, Long.valueOf(value), force);
         }
     
     
    -    synchronized void set(Setting setting, Long value) {
    +    /**
    +     * Specify a new value for setting with the option to force the change to take effect immediately rather than
    +     * waiting until an {@code ACK} is received.
    +     *
    +     * @param setting The setting to update
    +     * @param value   The new value for the setting
    +     * @param force   {@code false} if an {@code ACK} must be received before the setting takes effect or {@code true}
    +     *                    if the setting to take effect immediately. Even if the setting takes effect immediately, it
    +     *                    will still be included in the next {@code SETTINGS} frame and an {@code ACK} will be expected.
    +     */
    +    synchronized void set(Setting setting, Long value, boolean force) {
             current.put(setting, value);
         }
     
    
  • java/org/apache/coyote/http2/ConnectionSettingsLocal.java+4 1 modified
    @@ -40,12 +40,15 @@ class ConnectionSettingsLocal extends ConnectionSettingsBase<IllegalArgumentExce
     
     
         @Override
    -    final synchronized void set(Setting setting, Long value) {
    +    final synchronized void set(Setting setting, Long value, boolean force) {
             checkSend();
             if (current.get(setting).longValue() == value.longValue()) {
                 pending.remove(setting);
             } else {
                 pending.put(setting, value);
    +            if (force) {
    +                current.put(setting, value);
    +            }
             }
         }
     
    
  • java/org/apache/coyote/http2/Http2UpgradeHandler.java+6 2 modified
    @@ -163,8 +163,12 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
             remoteSettings = new ConnectionSettingsRemote(connectionId);
             localSettings = new ConnectionSettingsLocal(connectionId);
     
    -        localSettings.set(Setting.MAX_CONCURRENT_STREAMS, protocol.getMaxConcurrentStreams());
    -        localSettings.set(Setting.INITIAL_WINDOW_SIZE, protocol.getInitialWindowSize());
    +        /*
    +         * Force set these initial limits. A well-behaved client should ACK the settings and adhere to them before it
    +         * reaches the limits anyway.
    +         */
    +        localSettings.set(Setting.MAX_CONCURRENT_STREAMS, protocol.getMaxConcurrentStreams(), true);
    +        localSettings.set(Setting.INITIAL_WINDOW_SIZE, protocol.getInitialWindowSize(), true);
     
             pingManager.initiateDisabled = protocol.getInitiatePingDisabled();
     
    
  • webapps/docs/changelog.xml+4 0 modified
    @@ -161,6 +161,10 @@
             application tries to use CLIENT-CERT with either HTTP/2 or a JSSE
             implementation of TLS 1.3. (markt)
           </fix>
    +      <fix>
    +        When setting the initial HTTP/2 connection limit, apply those limits
    +        earlier. (markt)
    +      </fix>
         </changelog>
       </subsection>
       <subsection name="Jasper">
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

8

News mentions

0

No linked articles in our index yet.