Sep 25, 2026·8 min read·33 visits
Unbounded variable-length integer decoding in the python-hyper/hpack library enables unauthenticated remote attackers to trigger 100% CPU exhaustion and Denial of Service via malformed HTTP/2 frame headers.
CVE-2026-59980 is a CPU exhaustion vulnerability in python-hyper/hpack, where an unauthenticated remote attacker can trigger an infinite loop or high computational complexity overhead by sending a crafted HTTP/2 stream containing excessive variable-length integer continuation octets.
The python-hyper/hpack library is the standard Python implementation of the HTTP/2 Header Compression (HPACK) protocol, defined in RFC 7541. This library is integrated into ASGI servers, HTTP/2 application frameworks, and HTTP/2 clients to parse compressed HTTP headers. Because headers represent the initial entry point for processing incoming HTTP requests, any flaw in the decompression engine exposes a direct, unauthenticated network-facing attack surface.
CVE-2026-59980 identifies an uncontrolled resource consumption vulnerability (CWE-400) within the variable-length integer parsing mechanism of the HPACK decoder. Specifically, the library fails to restrict the quantity of continuation octets it processes when decoding HPACK-encoded integers. When processing a malformed stream containing highly padded integer representations, the decoder enters an expensive computation loop that exhibits quadratic algorithmic complexity relative to input size.
The resulting resource exhaustion causes the executing Python thread or process to consume 100% CPU. Because many Python application deployments rely on a single-threaded execution model or a limited worker pool, a single unauthenticated HTTP/2 frame can completely deny service to the underlying application. This vulnerability impacts all installations of the python-hyper/hpack library prior to version 4.2.0.
To compress headers efficiently, RFC 7541 specifies a prefix-based, variable-length integer representation. This format uses an N-bit prefix within the first octet of the stream. If the integer is smaller than 2^N - 1, it is fully contained within the prefix. If the integer is equal to or greater than 2^N - 1, all prefix bits are set to 1, and the remainder of the integer is encoded as a series of seven-bit blocks across subsequent continuation octets.
For each continuation octet, the most significant bit (MSB) acts as a continuation flag. An MSB of 1 indicates that another octet follows, while an MSB of 0 indicates the final octet of the integer. RFC 7541 explicitly instructs implementations to enforce limits on the value and octet length of integer encodings to prevent implementation-specific resource limits from being exceeded.
The root cause of CVE-2026-59980 is that the decode_integer function in src/hpack/hpack.py did not enforce any upper limit on the number of continuation octets. Because Python transparently manages arbitrary-precision integers (bignums), there is no hardware-level register overflow to terminate the loop or trigger an exception. Instead, the decoder continues to parse continuation octets, repeatedly performing bit-shift and addition operations.
As the parsed integer value grows larger, the computational overhead of these bignum operations increases. For an input sequence of length N continuation octets, the system must perform arithmetic operations on integers whose bit length scales linearly with N. This behavior translates to O(N^2) computational complexity, transforming a routine decoding operation into a runaway CPU loop that blocks the thread until exhaustion occurs.
Prior to the release of version 4.2.0, the decoding loop inside src/hpack/hpack.py was implemented without bounds checks on the number of processed octets. The loop parsed incoming data continuously until an octet with an MSB of 0 was encountered, or until an IndexError occurred due to reaching the end of the byte stream.
# Vulnerable implementation of decode_integer in src/hpack/hpack.py
def decode_integer(data: bytes | memoryview, prefix_bits: int) -> tuple[int, int]:
# ... prefix calculations ...
value = limit
shift = 0
index = 1
try:
while True:
byte = data[index]
index += 1
value += (byte & 127) << shift # Unbounded bit shift & addition on Python bignum
if (byte & 128) == 0:
break
shift += 7
except IndexError as err:
msg = f"Unable to decode HPACK integer representation from {data!r}"
raise HPACKDecodingError(msg) from errThe patch introduces a hard limit on the number of continuation octets, defined by the constant VARINT_MAX_LENGTH = 5. Five octets provide 35 bits of capacity, which is sufficient to encode any standard 32-bit unsigned integer while protecting the engine from excessive bignum calculations. If the byte-offset index exceeds this maximum length during the parsing loop, the decoder aborts operation immediately by raising an HPACKDecodingError.
# Patched implementation in src/hpack/hpack.py
VARINT_MAX_LENGTH = 5 # octets, enough for encoding prefix + uint32
def decode_integer(data: bytes | memoryview, prefix_bits: int) -> tuple[int, int]:
# ... prefix calculations ...
value = limit
shift = 0
index = 1
try:
while True:
byte = data[index]
index += 1
value += (byte & 127) << shift
if (byte & 128) == 0:
break
shift += 7
if index > VARINT_MAX_LENGTH: # Enforce limit to block runaway bignum loops
msg = f"Variable integer representation is too long: {data!r}"
raise HPACKDecodingError(msg)The introduction of VARINT_MAX_LENGTH restricts the execution of the loop to a maximum of five iterations per integer representation. This effectively bounds the computational complexity to O(1) for any individual integer, mitigating the quadratic performance degradation. The fix is complete for its intended scope, preventing uncontrolled loop execution while remaining compliant with RFC 7541 requirements.
Exploiting CVE-2026-59980 requires the ability to send standard HTTP/2 frames to a vulnerable target application server. The attacker does not need authentication or specialized system permissions. The primary requirement is that the target server utilizes a Python-based HTTP/2 server stack, such as hyper-h2, which depends on the hpack library to parse compressed request headers.
The attack vector operates by crafting a malicious HTTP/2 frame, such as a HEADERS or PUSH_PROMISE frame. The frame payload is structured to trigger the HPACK integer decoding loop. The attacker begins by setting the prefix-bits of the initial octet to the maximum value (e.g., 5 prefix bits set to 31, representing 0x1F). This informs the parser that the integer value continues in subsequent bytes.
The attacker then appends a large sequence of continuation octets where the high-order bit (MSB) is set to 1. For example, a sequence of thousands of 0xFF bytes is appended. Because each 0xFF byte has its high bit set, the decode_integer loop continues to execute. With every iteration, the Python interpreter dynamically allocates memory and performs arithmetic operations on an increasingly large arbitrary-precision integer.
A single connection sending a frame with 50,000 continuation octets will force the target thread into a CPU-bound loop lasting several seconds or minutes. Because of Python's Global Interpreter Lock (GIL), this CPU-intensive operation can block execution across other threads in the same process, multiplying the impact. An attacker can send multiple concurrent requests to consume all available worker processes on the host.
The security impact of CVE-2026-59980 is primarily focused on system availability. Successful exploitation allows an unauthenticated remote attacker to induce a complete Denial of Service (DoS) of the target web application. By sending a small, highly compressed payload, the attacker causes disproportionate CPU consumption on the backend server, achieving high asymmetric leverage.
The vulnerability is rated with a CVSS v4.0 score of 6.3 (Medium). The score reflects a high impact on Availability (VA:L on a single instance, but easily scalable to total service disruption in multi-tenant environments) and low Attack Complexity (AC:L). No user interaction or prior system privileges are required to exploit the flaw.
The EPSS score for this vulnerability is 0.00301, representing a low immediate probability of active exploitation in the wild. No active exploitation has been reported in the CISA Known Exploited Vulnerabilities (KEV) catalog. However, because the proof of concept is highly reliable and straightforward to implement, any directly exposed application running an unpatched version remains at risk of trivial denial-of-service attacks.
The definitive resolution for CVE-2026-59980 is upgrading the hpack library to version 4.2.0 or later. This version introduces the explicit limit of five continuation octets and raises an HPACKDecodingError when the threshold is exceeded. System administrators should verify downstream dependencies, such as h2, to ensure they pull in the updated version of hpack.
If patching the library immediately is not feasible, infrastructure-level mitigations can protect vulnerable applications. Placing a robust, hardened reverse proxy, such as Nginx, HAProxy, or an enterprise-grade Web Application Firewall (WAF), in front of the Python application is highly effective. These proxies terminate incoming HTTP/2 TLS connections and parse headers using highly optimized, memory-safe engines that enforce strict length boundaries.
For environments where proxy-level termination is not available, runtime network monitoring should be employed to flag anomalous HTTP/2 traffic. Snort or Suricata IDS rules can be configured to detect HTTP/2 frame payloads containing excessive repetitive sequences of octets with the MSB set. However, because the payload is typically encrypted via TLS, network-level detection must occur at the TLS termination endpoint.
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
hpack python-hyper | >= 1.0.0, < 4.2.0 | 4.2.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-400 |
| Attack Vector | Network |
| CVSS v4.0 Score | 6.3 |
| EPSS Score | 0.00301 (20.30% percentile) |
| Impact | Denial of Service (CPU Exhaustion) |
| Exploit Status | Proof of Concept |
| CISA KEV Status | Not Listed |
Uncontrolled Resource Consumption
CVE-2026-16454 is an object-level authorization bypass vulnerability (CWE-284, CWE-862) in Eclipse hawkBit versions 1.0.3 and prior. The flaw exists within the Direct Device Integration (DDI) REST controller (hawkbit-ddi-resource), where endpoints responsible for enumerating software module metadata and serving firmware binaries fail to verify whether the requested software module is assigned to the authenticated device. Consequently, any device with valid credentials (such as a TargetToken or GatewayToken) can enumerate software module identifiers and download arbitrary firmware artifacts across the entire tenant namespace.
CVE-2026-62284 (GHSA-5w5g-j6hw-6p8f) is a code injection and server-side request forgery vulnerability in the console-proxy component of the OSAC Operator. The RemoteConfigResolver parses Kubernetes Secrets containing kubeconfig files via clientcmd.RESTConfigFromKubeConfig without sanitizing execution-related fields. An attacker with RBAC permissions to create or modify labeled Secrets in monitored namespaces can supply a malicious exec credential plugin, resulting in arbitrary command execution within the console-proxy pod.
CVE-2026-62361 (GHSA-xgjr-7j9q-2h4r) is an authenticated SQL injection and authorization bypass vulnerability in listmonk, an open-source, self-hosted newsletter and mailing list manager written in Go. In versions prior to 6.2.0, the subscriber export endpoint (GET /api/subscribers/export) directly interpolates user-supplied SQL filter expressions into a PostgreSQL query without invoking the table allowlist validation function (validateQueryTables). Consequently, authenticated users possessing the subscribers:sql_query and subscribers:get_all permissions can bypass relational access controls, execute arbitrary subqueries against restricted tables such as users and settings, and modify database state via writable Common Table Expressions (CTEs).
CVE-2026-28385 (GHSA-3gq2-x4qg-p4g6) is a Server-Side Request Forgery (SSRF) vulnerability in Canonical LXD versions 4.12 through 6.9. An authenticated user possessing the can_create_images entitlement can force the LXD daemon to execute arbitrary outbound HTTP and HTTPS requests via the /1.0/images API endpoint. Due to the absence of egress destination validation, an attacker can probe host loopback services, RFC 1918 private network segments, and cloud Instance Metadata Services (IMDS) from the network position of the privileged LXD daemon.
Canonical LXD and LXC Incus contain an arbitrary file write vulnerability (CWE-73 / CWE-59) in the `/1.0/instances/<name>/exec` REST API endpoint. When an instance is unpacked from an image archive, top-level symbolic links are extracted directly onto the host filesystem within the instance storage directory. If a crafted image includes a symbolic link named `exec-output` pointing to an arbitrary host path, invoking the execution endpoint with `record-output: true` causes the privileged host daemon to follow the symlink and write command output files directly to the target host directory. An authenticated attacker with permissions to import images and execute commands can exploit this flaw to write controlled content to sensitive host directories such as `/etc/cron.d`, resulting in arbitrary code execution on the host as `root`.
CVE-2026-48749 (tracked as GHSA-vghh-5rfx-xhq8 for LXD and GHSA-2q3f-q5pq-g8wv for Incus) is a critical container escape vulnerability in the Canonical LXD and Linux Containers Incus system container managers. By importing a specially crafted container image archive containing duplicate tar member headers, an authenticated attacker can replace the instance rootfs directory with a symbolic link pointing to the underlying host root filesystem. When performing file operations on a stopped container, the privileged forkfile helper binary resolves the symbolic link without confinement and chroots directly into the host filesystem, granting arbitrary root-level file read and write access.