CVE-2026-109584
HTTP/2 cookie crumb join expands a small HPACK header block into an unbounded allocation in Bandit
Improper Handling of Highly Compressed Data (Data Amplification) vulnerability in the HTTP/2 implementation of mtrudel bandit allows an unauthenticated remote attacker to exhaust server memory via a small HPACK-compressed HEADERS block. The block stores one large cookie value in the HPACK dynamic table and then references it tens of thousands of times with 1-byte indexed fields. In the reporter's run, a 49 KB block made a server with default settings allocate a 183 MB cookie binary before any application code ran, and every concurrent stream can repeat the cost.
Bandit.HTTP2.Connection caps only the compressed block (max_header_block_size), and its check of the decoded list against max_header_list_size never fires because that setting defaults to :infinity. combine_cookie_crumbs/1 in lib/bandit/http2/stream.ex then joins every crumb into one binary.
This issue affects bandit: from 0.3.3 before 1.14.0.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- None
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
8.7
HTTP/2 cookie crumb join expands a small HPACK header block into an unbounded allocation in Bandit
Improper Handling of Highly Compressed Data (Data Amplification) vulnerability in the HTTP/2 implementation of mtrudel bandit allows an unauthenticated remote attacker to exhaust server memory via a small HPACK-compressed HEADERS block. The block stores one large cookie value in the HPACK dynamic table and then references it tens of thousands of times with 1-byte indexed fields. In the reporter's run, a 49 KB block made a server with default settings allocate a 183 MB cookie binary before any application code ran, and every concurrent stream can repeat the cost.
Bandit.HTTP2.Connection caps only the compressed block (max_header_block_size), and its check of the decoded list against max_header_list_size never fires because that setting defaults to :infinity. combine_cookie_crumbs/1 in lib/bandit/http2/stream.ex then joins every crumb into one binary.
This issue affects bandit: from 0.3.3 before 1.14.0.
- Record
CVE-2026-109584- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - Weakness
- CWE-409
- Updated
- 2026-11-02
EUVDEUVD-2026-109826
8.7
Improper Handling of Highly Compressed Data (Data Amplification) vulnerability in the HTTP/2 implementation of mtrudel bandit allows an unauthenticated remote attacker to exhaust server memory via a small HPACK-compressed HEADERS block. The block stores one large cookie value in the HPACK dynamic table and then references it tens of thousands of times with 1-byte indexed fields. In the reporter's run, a 49 KB block made a server with default settings allocate a 183 MB cookie binary before any application code ran, and every concurrent stream can repeat the cost.
Bandit.HTTP2.Connection caps only the compressed block (max_header_block_size), and its check of the decoded list against max_header_list_size never fires because that setting defaults to :infinity. combine_cookie_crumbs/1 in lib/bandit/http2/stream.ex then joins every crumb into one binary.
This issue affects bandit: from 0.3.3 before 1.14.0.
- Record
EUVD-2026-109826- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - Updated
- 2026-11-02
NVD
8.7
Improper Handling of Highly Compressed Data (Data Amplification) vulnerability in the HTTP/2 implementation of mtrudel bandit allows an unauthenticated remote attacker to exhaust server memory via a small HPACK-compressed HEADERS block. The block stores one large cookie value in the HPACK dynamic table and then references it tens of thousands of times with 1-byte indexed fields. In the reporter's run, a 49 KB block made a server with default settings allocate a 183 MB cookie binary before any application code ran, and every concurrent stream can repeat the cost.
Bandit.HTTP2.Connection caps only the compressed block (max_header_block_size), and its check of the decoded list against max_header_list_size never fires because that setting defaults to :infinity. combine_cookie_crumbs/1 in lib/bandit/http2/stream.ex then joins every crumb into one binary.
This issue affects bandit: from 0.3.3 before 1.14.0.
- Record
CVE-2026-109584- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - Weakness
- CWE-409
- Updated
- 2026-11-02
OSV
8.7
HTTP/2 cookie crumb join expands a small HPACK header block into an unbounded allocation in Bandit
Improper Handling of Highly Compressed Data (Data Amplification) vulnerability in the HTTP/2 implementation of mtrudel bandit allows an unauthenticated remote attacker to exhaust server memory via a small HPACK-compressed HEADERS block. The block stores one large cookie value in the HPACK dynamic table and then references it tens of thousands of times with 1-byte indexed fields. In the reporter's run, a 49 KB block made a server with default settings allocate a 183 MB cookie binary before any application code ran, and every concurrent stream can repeat the cost.
Bandit.HTTP2.Connection caps only the compressed block (max_header_block_size), and its check of the decoded list against max_header_list_size never fires because that setting defaults to :infinity. combine_cookie_crumbs/1 in lib/bandit/http2/stream.ex then joins every crumb into one binary.
This issue affects bandit: from 0.3.3 before 1.14.0.
- Record
CVE-2026-109584- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - Weakness
- CWE-409
- Updated
- 2026-11-02
OSVEEF-CVE-2026-109584
8.7
HTTP/2 cookie crumb join expands a small HPACK header block into an unbounded allocation in Bandit
Summary
Improper Handling of Highly Compressed Data (Data Amplification) vulnerability in the HTTP/2 implementation of mtrudel bandit allows an unauthenticated remote attacker to exhaust server memory via a small HPACK-compressed HEADERS block. The block stores one large cookie value in the HPACK dynamic table and then references it tens of thousands of times with 1-byte indexed fields. In the reporter's run, a 49 KB block made a server with default settings allocate a 183 MB cookie binary before any application code ran, and every concurrent stream can repeat the cost.
Bandit.HTTP2.Connection caps only the compressed block (max_header_block_size), and its check of the decoded list against max_header_list_size never fires because that setting defaults to :infinity. combine_cookie_crumbs/1 in lib/bandit/http2/stream.ex then joins every crumb into one binary.
This issue affects bandit: from 0.3.3 before 1.14.0.
Details
1. Compression
The attacker's header block, split across HEADERS and CONTINUATION frames, stays under the 50,000-byte max_header_block_size. It inserts one 4,058-byte cookie into the 4,096-byte dynamic table, the largest value that fits, then references it about 45,000 times with 1-byte indexed representations. HPAX.decode returns a list whose entries all point at the same binary, so decoding itself stays cheap.
2. Missing decoded limit (lib/bandit/http2/connection.ex, lib/bandit/http2/settings.ex)
After decoding, the connection compares header_list_size(headers) against local_settings.max_header_list_size. That setting defaults to :infinity, and in Erlang term order every integer sorts below an atom, so the comparison never rejects a list. The limit is enforced only when an operator sets it.
3. Expansion (lib/bandit/http2/stream.ex)
read_headers calls combine_cookie_crumbs/1, which joins every crumb with Enum.map_join/3 into a single binary of about 183 MB before Plug.call/2 runs. max_concurrent_streams also defaults to :infinity, so N streams allocate N times as much.
Proof of concept
- Against a Bandit server with default HTTP/2 settings, build an HPACK header block with the request pseudo-headers plus a 4,058-byte
cookiestored in the dynamic table and then referenced about 45,000 times with indexed representations. The block is about 49 KB. - Send it on one stream as a HEADERS frame followed by CONTINUATION frames of at most 16,384 bytes, with
END_HEADERSon the last. - The request reaches the plug with a
cookieheader of about 183 MB, and VM memory grows by about the same amount. Repeat on further streams to multiply it.
Impact
An unauthenticated remote client can make any Bandit server with default HTTP/2 settings allocate a cookie binary thousands of times larger than the header block it sent, before any application code runs. Repeating it across concurrent streams exhausts the BEAM node's memory, taking down every application on the node.
Workarounds
On 1.12.2 and later, set a finite decoded header list limit, for example http_2_options: [default_local_settings: [max_header_list_size: 65_536]], which resets the stream before the cookie crumbs are joined. From 0.7.0, disabling HTTP/2 with http_2_options: [enabled: false] removes the vulnerable path.
- Record
EEF-CVE-2026-109584- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - Weakness
- CWE-409
- Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-109584
8.7
Improper Handling of Highly Compressed Data (Data Amplification) vulnerability in the HTTP/2 implementation of mtrudel bandit allows an unauthenticated remote attacker to exhaust server memory via a small HPACK-compressed HEADERS block. The block stores one large cookie value in the HPACK dynamic table and then references it tens of thousands of times with 1-byte indexed fields. In the reporter's run, a 49 KB block made a server with default settings allocate a 183 MB cookie binary before any application code ran, and every concurrent stream can repeat the cost. Bandit.HTTP2.Connection caps only the compressed block (max_header_block_size), and its check of the decoded list against max_header_list_size never fires because that setting defaults to :infinity. combine_cookie_crumbs/1 in lib/bandit/http2/stream.ex then joins every crumb into one binary. This issue affects bandit: from 0.3.3 before 1.14.0.
- Record
UBUNTU-CVE-2026-109584- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
banditHex |
0.3.3 up to 1.14.0, plus listed versions 0.3.40.3.50.3.60.3.70.3.8 Show 45 moreShow less0.3.90.4.00.4.10.4.100.4.20.4.30.4.40.4.50.4.60.4.70.4.80.4.90.5.00.5.10.5.100.5.110.5.20.5.30.5.40.5.50.5.60.5.70.5.80.5.90.6.00.6.10.6.100.6.110.6.20.6.30.6.40.6.50.6.60.6.70.6.80.6.90.7.00.7.10.7.20.7.30.7.40.7.50.7.60.7.71.0.0 |
1.14.0 |
banditUbuntu:16.04:LTS |
All versions, plus listed versions 0.13.2-10.13.2-3 |
None known |
banditUbuntu:18.04:LTS |
All versions, plus listed versions 1.4.0-0ubuntu2 |
None known |
banditUbuntu:20.04:LTS |
All versions, plus listed versions 1.5.1-31.6.2-1 |
None known |
banditUbuntu:22.04:LTS |
All versions, plus listed versions 1.6.2-1 |
None known |
banditUbuntu:24.04:LTS |
All versions, plus listed versions 1.6.2-3 |
None known |
banditUbuntu:26.10 |
All versions, plus listed versions 1.7.10-31.9.4-1 |
None known |
banditUbuntu:26.04:LTS |
All versions, plus listed versions 1.7.10-21.7.10-3 |
None known |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-109584 is a high vulnerability (CVSS 8.7) in Mtrudel Bandit, published October 26, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.60%, the 49th percentile. Fixed in bandit 1.14.0.
References
github.com/mtrudel/bandit/security/advisories/GHSA-7gfj-7gvq-3xqj
cna.erlef.org/cves/CVE-2026-109584.html
osv.dev/vulnerability/EEF-CVE-2026-109584
github.com/mtrudel/bandit/commit/44bf969cd59851622fb6ee4d16227fbc39a77fb4
github.com/mtrudel/bandit/commit/220b9dfd27f9a21305be2afc75cbe585ddc24e7a
github.com
Show 12 moreShow less
repo.hex.pm
github.com/CVEProject/cvelistV5/tree/main/cves/2026/109xxx/CVE-2026-109584.json
nvd.nist.gov/vuln/detail/CVE-2026-109584
github.com/mtrudel/bandit
hex.pm/packages/bandit
ubuntu.com/security/CVE-2026-109584
cve.org/CVERecord?id=CVE-2026-109584
cna.erlef.org/cves/cve-2026-109584.html
github.com/mtrudel/bandit/security/advisories/ghsa-7gfj-7gvq-3xqj
github.com/cveproject/cvelistv5/tree/main/cves/2026/109xxx/cve-2026-109584.json
nvd.nist.gov/vuln/detail/cve-2026-109584
osv.dev/vulnerability/eef-cve-2026-109584
Left out here: 68 versions. The JSON record has them.