CVE-2020-11996
Description
A specially crafted sequence of HTTP/2 requests sent to Apache Tomcat 10.0.0-M1 to 10.0.0-M5, 9.0.0.M1 to 9.0.35 and 8.5.0 to 8.5.55 could trigger high CPU usage for several seconds. If a sufficient number of such requests were made on concurrent HTTP/2 connections, the server could become unresponsive.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
A specially crafted sequence of HTTP/2 requests can cause high CPU usage and denial of service in Apache Tomcat versions 8.5.0-8.5.55, 9.0.0.M1-9.0.35, and 10.0.0-M1-10.0.0-M5.
Vulnerability
CVE-2020-11996 is a denial-of-service vulnerability in Apache Tomcat's HTTP/2 handling. The root cause is that a specially crafted sequence of HTTP/2 requests can trigger excessive CPU consumption for several seconds. This occurs when the server processes malformed or specially constructed frames that cause expensive internal operations, leading to a temporary resource exhaustion spike. [1][2][3]
Exploitation
The attack does not require authentication; an unauthenticated remote attacker can send a small number of malicious HTTP/2 requests to trigger the condition. However, to make the server unresponsive, an attacker needs to send such requests concurrently across multiple HTTP/2 connections. The vulnerability is network-based and does not require any special privileges beyond the ability to establish an HTTP/2 connection to the server. [4]
Impact
A successful exploitation results in high CPU usage for several seconds. If a sufficient number of concurrent requests are made, the server can become completely unresponsive, effectively leading to a denial-of-service (DoS) condition. This can impact availability of web applications hosted on the affected Tomcat versions. No code execution or data breach is associated with this vulnerability. [4]
Mitigation
Apache Tomcat has released security updates to fix this issue. The vulnerability is fixed in Tomcat 8.5.56, 9.0.36, and 10.0.0-M6 or later. Users should upgrade to these patched versions. No workaround is provided for this vulnerability. [1][2][3]
AI Insight generated on May 21, 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.
| Package | Affected versions | Patched versions |
|---|---|---|
org.apache.tomcat:tomcatMaven | >= 10.0.0-M1, < 10.0.0-M5 | 10.0.0-M5 |
org.apache.tomcat:tomcatMaven | >= 9.0.0.M1, < 9.0.35 | 9.0.35 |
org.apache.tomcat:tomcatMaven | >= 8.5.0, < 8.5.55 | 8.5.55 |
Affected products
19- osv-coords18 versionspkg:bitnami/tomcatpkg:maven/org.apache.tomcat/tomcatpkg:rpm/opensuse/tomcat10&distro=openSUSE%20Tumbleweedpkg:rpm/opensuse/tomcat&distro=openSUSE%20Leap%2015.1pkg:rpm/opensuse/tomcat&distro=openSUSE%20Leap%2015.2pkg:rpm/opensuse/tomcat&distro=openSUSE%20Tumbleweedpkg:rpm/suse/tomcat&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015-ESPOSpkg:rpm/suse/tomcat&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015-LTSSpkg:rpm/suse/tomcat&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Web%20and%20Scripting%2015%20SP1pkg:rpm/suse/tomcat&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Web%20and%20Scripting%2015%20SP2pkg:rpm/suse/tomcat&distro=SUSE%20Linux%20Enterprise%20Server%2012%20SP4-LTSSpkg:rpm/suse/tomcat&distro=SUSE%20Linux%20Enterprise%20Server%2012%20SP5pkg:rpm/suse/tomcat&distro=SUSE%20Linux%20Enterprise%20Server%2015-LTSSpkg:rpm/suse/tomcat&distro=SUSE%20Linux%20Enterprise%20Server%20for%20SAP%20Applications%2012%20SP4pkg:rpm/suse/tomcat&distro=SUSE%20Linux%20Enterprise%20Server%20for%20SAP%20Applications%2012%20SP5pkg:rpm/suse/tomcat&distro=SUSE%20Linux%20Enterprise%20Server%20for%20SAP%20Applications%2015pkg:rpm/suse/tomcat&distro=SUSE%20OpenStack%20Cloud%209pkg:rpm/suse/tomcat&distro=SUSE%20OpenStack%20Cloud%20Crowbar%209
>= 8.5.0, < 8.5.56+ 17 more
- (no CPE)range: >= 8.5.0, < 8.5.56
- (no CPE)range: >= 10.0.0-M1, < 10.0.0-M5
- (no CPE)range: < 10.1.14-1.1
- (no CPE)range: < 9.0.36-lp151.3.24.1
- (no CPE)range: < 9.0.36-lp152.2.3.1
- (no CPE)range: < 9.0.36-8.4
- (no CPE)range: < 9.0.36-3.60.1
- (no CPE)range: < 9.0.36-3.60.1
- (no CPE)range: < 9.0.36-4.38.1
- (no CPE)range: < 9.0.36-3.3.1
- (no CPE)range: < 9.0.36-3.42.2
- (no CPE)range: < 9.0.36-3.42.2
- (no CPE)range: < 9.0.36-3.60.1
- (no CPE)range: < 9.0.36-3.42.2
- (no CPE)range: < 9.0.36-3.42.2
- (no CPE)range: < 9.0.36-3.60.1
- (no CPE)range: < 9.0.36-3.42.2
- (no CPE)range: < 9.0.36-3.42.2
- Apache/Apache Tomcatv5Range: 10.0.0-M1 to 10.0.0-M5
Patches
39434a44d3449Fix BZ 64467. Improve performance of closing idle streams
3 files changed · +36 −9
java/org/apache/coyote/http2/Http2UpgradeHandler.java+5 −5 modified@@ -1473,11 +1473,11 @@ public HeaderEmitter headersStart(int streamId, boolean headersEndStream) } - private void closeIdleStreams(int newMaxActiveRemoteStreamId) throws Http2Exception { - for (int i = maxActiveRemoteStreamId + 2; i < newMaxActiveRemoteStreamId; i += 2) { - Stream stream = getStream(i, false); - if (stream != null) { - stream.closeIfIdle(); + private void closeIdleStreams(int newMaxActiveRemoteStreamId) { + for (Entry<Integer,Stream> entry : streams.entrySet()) { + if (entry.getKey().intValue() > maxActiveRemoteStreamId && + entry.getKey().intValue() < newMaxActiveRemoteStreamId) { + entry.getValue().closeIfIdle(); } } maxActiveRemoteStreamId = newMaxActiveRemoteStreamId;
test/org/apache/coyote/http2/TestHttp2Section_5_1.java+27 −4 modified@@ -147,21 +147,44 @@ public void testClientSendOldStream() throws Exception { @Test public void testImplicitClose() throws Exception { + doTestImplicitClose(5); + } + + + // https://bz.apache.org/bugzilla/show_bug.cgi?id=64467 + @Test + public void testImplicitCloseLargeId() throws Exception { + doTestImplicitClose(Integer.MAX_VALUE - 8); + } + + + private void doTestImplicitClose(int lastStreamId) throws Exception { + + long startFirst = System.nanoTime(); http2Connect(); + long durationFirst = System.nanoTime() - startFirst; sendPriority(3, 0, 16); - sendPriority(5, 0, 16); + sendPriority(lastStreamId, 0, 16); - sendSimpleGetRequest(5); + long startSecond = System.nanoTime(); + sendSimpleGetRequest(lastStreamId); readSimpleGetResponse(); - Assert.assertEquals(getSimpleResponseTrace(5), output.getTrace()); + long durationSecond = System.nanoTime() - startSecond; + + Assert.assertEquals(getSimpleResponseTrace(lastStreamId), output.getTrace()); output.clearTrace(); + // Allow second request to take up to 5 times first request or up to 1 second - whichever is the larger - mainly + // to allow for CI systems under load that can exhibit significant timing variation. + Assert.assertTrue("First request took [" + durationFirst/1000000 + "ms], second request took [" + + durationSecond/1000000 + "ms]", durationSecond < 1000000000 || durationSecond < durationFirst * 3); + // Should trigger an error since stream 3 should have been implicitly // closed. sendSimpleGetRequest(3); - handleGoAwayResponse(5); + handleGoAwayResponse(lastStreamId); }
webapps/docs/changelog.xml+4 −0 modified@@ -71,6 +71,10 @@ <update> Add support for ALPN on recent OpenJDK 8 releases. (remm) </update> + <fix> + <bug>64467</bug>: Improve performance of closing idle HTTP/2 streams. + (markt) + </fix> </changelog> </subsection> <subsection name="WebSocket">
c8acd2ab7371Fix BZ 64467. Improve performance of closing idle streams
3 files changed · +36 −9
java/org/apache/coyote/http2/Http2UpgradeHandler.java+5 −5 modified@@ -1582,11 +1582,11 @@ public HeaderEmitter headersStart(int streamId, boolean headersEndStream) } - private void closeIdleStreams(int newMaxActiveRemoteStreamId) throws Http2Exception { - for (int i = maxActiveRemoteStreamId + 2; i < newMaxActiveRemoteStreamId; i += 2) { - Stream stream = getStream(i, false); - if (stream != null) { - stream.closeIfIdle(); + private void closeIdleStreams(int newMaxActiveRemoteStreamId) { + for (Entry<Integer,Stream> entry : streams.entrySet()) { + if (entry.getKey().intValue() > maxActiveRemoteStreamId && + entry.getKey().intValue() < newMaxActiveRemoteStreamId) { + entry.getValue().closeIfIdle(); } } maxActiveRemoteStreamId = newMaxActiveRemoteStreamId;
test/org/apache/coyote/http2/TestHttp2Section_5_1.java+27 −4 modified@@ -152,21 +152,44 @@ public void testClientSendOldStream() throws Exception { @Test public void testImplicitClose() throws Exception { + doTestImplicitClose(5); + } + + + // https://bz.apache.org/bugzilla/show_bug.cgi?id=64467 + @Test + public void testImplicitCloseLargeId() throws Exception { + doTestImplicitClose(Integer.MAX_VALUE - 8); + } + + + private void doTestImplicitClose(int lastStreamId) throws Exception { + + long startFirst = System.nanoTime(); http2Connect(); + long durationFirst = System.nanoTime() - startFirst; sendPriority(3, 0, 16); - sendPriority(5, 0, 16); + sendPriority(lastStreamId, 0, 16); - sendSimpleGetRequest(5); + long startSecond = System.nanoTime(); + sendSimpleGetRequest(lastStreamId); readSimpleGetResponse(); - Assert.assertEquals(getSimpleResponseTrace(5), output.getTrace()); + long durationSecond = System.nanoTime() - startSecond; + + Assert.assertEquals(getSimpleResponseTrace(lastStreamId), output.getTrace()); output.clearTrace(); + // Allow second request to take up to 5 times first request or up to 1 second - whichever is the larger - mainly + // to allow for CI systems under load that can exhibit significant timing variation. + Assert.assertTrue("First request took [" + durationFirst/1000000 + "ms], second request took [" + + durationSecond/1000000 + "ms]", durationSecond < 1000000000 || durationSecond < durationFirst * 3); + // Should trigger an error since stream 3 should have been implicitly // closed. sendSimpleGetRequest(3); - handleGoAwayResponse(5); + handleGoAwayResponse(lastStreamId); }
webapps/docs/changelog.xml+4 −0 modified@@ -63,6 +63,10 @@ <update> Add support for ALPN on recent OpenJDK 8 releases. (remm) </update> + <fix> + <bug>64467</bug>: Improve performance of closing idle HTTP/2 streams. + (markt) + </fix> </changelog> </subsection> <subsection name="WebSocket">
9a0231683a77Fix BZ 64467. Improve performance of closing idle streams
3 files changed · +36 −9
java/org/apache/coyote/http2/Http2UpgradeHandler.java+5 −5 modified@@ -1473,11 +1473,11 @@ public HeaderEmitter headersStart(int streamId, boolean headersEndStream) } - private void closeIdleStreams(int newMaxActiveRemoteStreamId) throws Http2Exception { - for (int i = maxActiveRemoteStreamId + 2; i < newMaxActiveRemoteStreamId; i += 2) { - Stream stream = getStream(i, false); - if (stream != null) { - stream.closeIfIdle(); + private void closeIdleStreams(int newMaxActiveRemoteStreamId) { + for (Entry<Integer,Stream> entry : streams.entrySet()) { + if (entry.getKey().intValue() > maxActiveRemoteStreamId && + entry.getKey().intValue() < newMaxActiveRemoteStreamId) { + entry.getValue().closeIfIdle(); } } maxActiveRemoteStreamId = newMaxActiveRemoteStreamId;
test/org/apache/coyote/http2/TestHttp2Section_5_1.java+27 −4 modified@@ -147,21 +147,44 @@ public void testClientSendOldStream() throws Exception { @Test public void testImplicitClose() throws Exception { + doTestImplicitClose(5); + } + + + // https://bz.apache.org/bugzilla/show_bug.cgi?id=64467 + @Test + public void testImplicitCloseLargeId() throws Exception { + doTestImplicitClose(Integer.MAX_VALUE - 8); + } + + + private void doTestImplicitClose(int lastStreamId) throws Exception { + + long startFirst = System.nanoTime(); http2Connect(); + long durationFirst = System.nanoTime() - startFirst; sendPriority(3, 0, 16); - sendPriority(5, 0, 16); + sendPriority(lastStreamId, 0, 16); - sendSimpleGetRequest(5); + long startSecond = System.nanoTime(); + sendSimpleGetRequest(lastStreamId); readSimpleGetResponse(); - Assert.assertEquals(getSimpleResponseTrace(5), output.getTrace()); + long durationSecond = System.nanoTime() - startSecond; + + Assert.assertEquals(getSimpleResponseTrace(lastStreamId), output.getTrace()); output.clearTrace(); + // Allow second request to take up to 5 times first request or up to 1 second - whichever is the larger - mainly + // to allow for CI systems under load that can exhibit significant timing variation. + Assert.assertTrue("First request took [" + durationFirst/1000000 + "ms], second request took [" + + durationSecond/1000000 + "ms]", durationSecond < 1000000000 || durationSecond < durationFirst * 3); + // Should trigger an error since stream 3 should have been implicitly // closed. sendSimpleGetRequest(3); - handleGoAwayResponse(5); + handleGoAwayResponse(lastStreamId); }
webapps/docs/changelog.xml+4 −0 modified@@ -71,6 +71,10 @@ <update> Add support for ALPN on recent OpenJDK 8 releases. (remm) </update> + <fix> + <bug>64467</bug>: Improve performance of closing idle HTTP/2 streams. + (markt) + </fix> </changelog> </subsection> <subsection name="WebSocket">
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
49- lists.opensuse.org/opensuse-security-announce/2020-07/msg00064.htmlghsavendor-advisoryx_refsource_SUSEWEB
- lists.opensuse.org/opensuse-security-announce/2020-07/msg00072.htmlghsavendor-advisoryx_refsource_SUSEWEB
- github.com/advisories/GHSA-53hp-jpwq-2jgqghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2020-11996ghsaADVISORY
- usn.ubuntu.com/4596-1/mitrevendor-advisoryx_refsource_UBUNTU
- www.debian.org/security/2020/dsa-4727ghsavendor-advisoryx_refsource_DEBIANWEB
- github.com/apache/tomcat/commit/9434a44d3449d620b1be70206819f8275b4a7509ghsaWEB
- github.com/apache/tomcat/commit/9a0231683a77e2957cea0fdee88b193b30b0c976ghsaWEB
- github.com/apache/tomcat/commit/c8acd2ab7371e39aeca7c306f3b5380f00afe552ghsaWEB
- lists.apache.org/thread.html/r2529016c311ce9485e6f173446d469600fdfbb94dccadfcd9dfdac79%40%3Cusers.tomcat.apache.org%3Emitremailing-listx_refsource_MLIST
- lists.apache.org/thread.html/r2529016c311ce9485e6f173446d469600fdfbb94dccadfcd9dfdac79@%3Cusers.tomcat.apache.org%3EghsaWEB
- lists.apache.org/thread.html/r3ea96d8f36dd404acce83df8aeb22a9e807d6c13ca9c5dec72f872cd%40%3Cnotifications.ofbiz.apache.org%3Emitremailing-listx_refsource_MLIST
- lists.apache.org/thread.html/r3ea96d8f36dd404acce83df8aeb22a9e807d6c13ca9c5dec72f872cd@%3Cnotifications.ofbiz.apache.org%3EghsaWEB
- lists.apache.org/thread.html/r5541ef6b6b68b49f76fc4c45695940116da2bcbe0312ef204a00a2e0%40%3Cannounce.tomcat.apache.org%3Eghsax_refsource_CONFIRMWEB
- lists.apache.org/thread.html/r5a4f80a6acc6607d61dae424b643b594c6188dd4e1eff04705c10db2%40%3Cnotifications.ofbiz.apache.org%3Emitremailing-listx_refsource_MLIST
- lists.apache.org/thread.html/r5a4f80a6acc6607d61dae424b643b594c6188dd4e1eff04705c10db2@%3Cnotifications.ofbiz.apache.org%3EghsaWEB
- lists.apache.org/thread.html/r6c29801370a36c1a5159679269777ad0c73276d3015b8bbefea66e5c%40%3Cnotifications.ofbiz.apache.org%3Emitremailing-listx_refsource_MLIST
- lists.apache.org/thread.html/r6c29801370a36c1a5159679269777ad0c73276d3015b8bbefea66e5c@%3Cnotifications.ofbiz.apache.org%3EghsaWEB
- lists.apache.org/thread.html/r74f5a8204efe574cbfcd95b2a16236fe95beb45c4d9fee3dc789dca9%40%3Ccommits.ofbiz.apache.org%3Emitremailing-listx_refsource_MLIST
- lists.apache.org/thread.html/r74f5a8204efe574cbfcd95b2a16236fe95beb45c4d9fee3dc789dca9@%3Ccommits.ofbiz.apache.org%3EghsaWEB
- lists.apache.org/thread.html/r8f3d416c193bc9384a8a7dd368623d441f5fcaff1057115008100561%40%3Ccommits.ofbiz.apache.org%3Emitremailing-listx_refsource_MLIST
- lists.apache.org/thread.html/r8f3d416c193bc9384a8a7dd368623d441f5fcaff1057115008100561@%3Ccommits.ofbiz.apache.org%3EghsaWEB
- lists.apache.org/thread.html/r8f7484589454638af527182ae55ef5b628ba00c05c5b11887c922fb1%40%3Cnotifications.ofbiz.apache.org%3Emitremailing-listx_refsource_MLIST
- lists.apache.org/thread.html/r8f7484589454638af527182ae55ef5b628ba00c05c5b11887c922fb1@%3Cnotifications.ofbiz.apache.org%3EghsaWEB
- lists.apache.org/thread.html/r93ca628ef3a4530dfe5ac49fddc795f0920a4b2a408b57a30926a42b%40%3Ccommits.ofbiz.apache.org%3Emitremailing-listx_refsource_MLIST
- lists.apache.org/thread.html/r93ca628ef3a4530dfe5ac49fddc795f0920a4b2a408b57a30926a42b@%3Ccommits.ofbiz.apache.org%3EghsaWEB
- lists.apache.org/thread.html/r9ad911fe49450ed9405827af0e7a74104041081ff91864b1f2546bbd%40%3Cnotifications.ofbiz.apache.org%3Emitremailing-listx_refsource_MLIST
- lists.apache.org/thread.html/r9ad911fe49450ed9405827af0e7a74104041081ff91864b1f2546bbd@%3Cnotifications.ofbiz.apache.org%3EghsaWEB
- lists.apache.org/thread.html/ra7092f7492569b39b04ec0decf52628ba86c51f15efb38f5853e2760%40%3Cnotifications.ofbiz.apache.org%3Emitremailing-listx_refsource_MLIST
- lists.apache.org/thread.html/ra7092f7492569b39b04ec0decf52628ba86c51f15efb38f5853e2760@%3Cnotifications.ofbiz.apache.org%3EghsaWEB
- lists.apache.org/thread.html/rb4ee49ecc4c59620ffd5e66e84a17e526c2c3cfa95d0cd682d90d338%40%3Cnotifications.ofbiz.apache.org%3Emitremailing-listx_refsource_MLIST
- lists.apache.org/thread.html/rb4ee49ecc4c59620ffd5e66e84a17e526c2c3cfa95d0cd682d90d338@%3Cnotifications.ofbiz.apache.org%3EghsaWEB
- lists.apache.org/thread.html/rb820f1a2a02bf07414be12c653c2ab5321fd87b9bf6c5e635c53ff4b%40%3Cnotifications.ofbiz.apache.org%3Emitremailing-listx_refsource_MLIST
- lists.apache.org/thread.html/rb820f1a2a02bf07414be12c653c2ab5321fd87b9bf6c5e635c53ff4b@%3Cnotifications.ofbiz.apache.org%3EghsaWEB
- lists.apache.org/thread.html/rc80b96b4b96618b2b7461cb90664a428cfd6605eea9f74e51b792542%40%3Cnotifications.ofbiz.apache.org%3Emitremailing-listx_refsource_MLIST
- lists.apache.org/thread.html/rc80b96b4b96618b2b7461cb90664a428cfd6605eea9f74e51b792542@%3Cnotifications.ofbiz.apache.org%3EghsaWEB
- lists.apache.org/thread.html/rea65d6ef2e45dd1c45faae83922042732866c7b88fa109b76c83db52%40%3Cnotifications.ofbiz.apache.org%3Emitremailing-listx_refsource_MLIST
- lists.apache.org/thread.html/rea65d6ef2e45dd1c45faae83922042732866c7b88fa109b76c83db52@%3Cnotifications.ofbiz.apache.org%3EghsaWEB
- lists.apache.org/thread.html/ref0339792ac6dac1dba83c071a727ad72380899bde60f6aaad4031b9%40%3Cnotifications.ofbiz.apache.org%3Emitremailing-listx_refsource_MLIST
- lists.apache.org/thread.html/ref0339792ac6dac1dba83c071a727ad72380899bde60f6aaad4031b9@%3Cnotifications.ofbiz.apache.org%3EghsaWEB
- lists.debian.org/debian-lts-announce/2020/07/msg00010.htmlghsamailing-listx_refsource_MLISTWEB
- security.netapp.com/advisory/ntap-20200709-0002ghsaWEB
- security.netapp.com/advisory/ntap-20200709-0002/mitrex_refsource_CONFIRM
- tomcat.apache.org/security-10.htmlghsaWEB
- tomcat.apache.org/security-8.htmlghsaWEB
- tomcat.apache.org/security-9.htmlghsaWEB
- usn.ubuntu.com/4596-1ghsaWEB
- www.oracle.com/security-alerts/cpujan2021.htmlghsax_refsource_MISCWEB
- www.oracle.com/security-alerts/cpuoct2020.htmlghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.