Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-54340

CVE-2026-54340: h2o HTTP Server DOS Vulnerability

CVE-2026-54340 is a denial of service flaw in h2o HTTP server combining HPACK decompression amplification with Slowloris-style attacks. This article covers technical details, affected versions, and mitigation.

Published:

CVE-2026-54340 Overview

CVE-2026-54340 affects the H2O HTTP server, which supports HTTP/1.x, HTTP/2, and HTTP/3 protocols. The vulnerability combines HPACK decompression amplification with Slowloris-style stream stalling in HTTP/2 connections. Attackers can retain amplified decoded header state through stalled HTTP/2 streams, leading to resource exhaustion on the server. The issue was resolved in commit 9265bdd, which introduces soft bounds on decoded header state via H2O_MAX_HEADERS and H2O_MAX_REQLEN constants. This weakness is classified under [CWE-400] Uncontrolled Resource Consumption.

Critical Impact

Remote unauthenticated attackers can exhaust server memory by combining HPACK header amplification with intentionally stalled HTTP/2 streams, resulting in denial of service.

Affected Products

  • H2O HTTP server versions prior to commit 9265bdd
  • Deployments using HTTP/2 with default HPACK decoding limits
  • Servers exposing H2O to untrusted network clients

Discovery Timeline

  • 2026-07-17 - CVE-2026-54340 published to NVD
  • 2026-07-17 - Last updated in NVD database

Technical Details for CVE-2026-54340

Vulnerability Analysis

The vulnerability is a denial-of-service condition rooted in HTTP/2 protocol handling. HPACK, the header compression format for HTTP/2, allows a compact wire representation to expand into significantly larger decoded header sets on the server. When H2O decodes these headers, the resulting state consumes memory proportional to the decompressed size rather than the received bytes.

Attackers combine this amplification with Slowloris-style behavior. Rather than completing streams, they open many HTTP/2 streams and leave them in a stalled state. Each stalled stream retains its amplified decoded header state in memory. Without upper bounds on retained decoded state, memory usage grows until the server can no longer service legitimate requests.

Root Cause

The H2O source tree did not enforce hard limits on the volume of decoded header state that stalled HTTP/2 streams could retain. Prior code paths defined H2O_MAX_HEADERS and H2O_MAX_REQLEN in include/h2o.h but treated them inconsistently as bounds during HPACK processing. Attackers exploited this gap to keep amplified header state alive across many concurrent streams.

Attack Vector

An unauthenticated remote attacker opens an HTTP/2 connection to a vulnerable H2O server. The attacker sends HPACK-compressed headers designed to expand into large decoded sets, then stalls each stream without completing the request. Repeating this across many streams consumes server memory until service degradation or outage occurs.

c
// Security patch in include/h2o/header.h
// Merge pull request #3597 from h2o/kazuho/hpack-bomb

#ifndef H2O_MAX_HEADERS
/**
 * Maximum number of fields expected in a field section. This is a soft target for processing input. Functions must be prepared for
 * processing field sections that have more fields than H2O_MAX_HEADERS.
 */
#define H2O_MAX_HEADERS 100
#endif

#ifndef H2O_MAX_REQLEN
/**
 * Maximum size of an encoded field section in bytes. This is a soft target for processing input. Functions must be prepared for
 * processing field sections that is larger than this (consider huffman decompression in HPACK).
 */
#define H2O_MAX_REQLEN (8192 + 4096 * (H2O_MAX_HEADERS))
#endif

typedef struct st_h2o_header_flags_t {
    unsigned char dont_compress : 1;
} h2o_header_flags_t;

Source: GitHub Commit 9265bdd. The patch relocates the H2O_MAX_HEADERS and H2O_MAX_REQLEN definitions into include/h2o/header.h with documentation clarifying they are soft targets. Downstream HPACK code paths use these bounds to constrain decoded header state.

Detection Methods for CVE-2026-54340

Indicators of Compromise

  • Sustained growth in H2O process resident memory without corresponding request completion rates
  • High counts of open HTTP/2 streams per connection remaining in a non-terminal state
  • Client connections sending compressed headers that decode to disproportionately large field sections
  • Elevated ratio of HPACK-decoded bytes to received HTTP/2 frame bytes on a single connection

Detection Strategies

  • Monitor HTTP/2 stream lifetimes and flag connections holding many streams open past reasonable request-processing windows
  • Track HPACK decompression ratios per connection and alert when decoded header size exceeds encoded payload by large multipliers
  • Correlate memory pressure alerts on H2O hosts with concurrent HTTP/2 connection counts and stream inventories

Monitoring Recommendations

  • Enable H2O access and error logging with sufficient verbosity to surface stream state and header sizes
  • Ingest H2O logs and host memory telemetry into a centralized analytics platform for correlation
  • Alert on repeated client source addresses that open many concurrent HTTP/2 streams without completing requests

How to Mitigate CVE-2026-54340

Immediate Actions Required

  • Update H2O to a build that includes commit 9265bdd or later
  • Audit deployed H2O configurations for HTTP/2 concurrency and header size limits
  • Restrict exposure of H2O HTTP/2 endpoints behind rate-limiting reverse proxies where feasible
  • Review the GitHub Security Advisory GHSA-qcrr-wrhc-pgq9 for vendor guidance

Patch Information

The fix is available in H2O commit 9265bdd9a996ed992681055e3996baf3e09d2063. It introduces documented soft bounds on decoded header state through H2O_MAX_HEADERS and H2O_MAX_REQLEN, and updates HPACK processing paths to honor them. See the GitHub Commit Changes for the full diff.

Workarounds

  • Reduce HTTP/2 maximum concurrent streams per connection in H2O configuration to limit stalled-stream inventory
  • Deploy an HTTP/2-aware reverse proxy in front of H2O to enforce header size and stream concurrency limits
  • Impose connection-level idle timeouts to reap stalled streams before memory pressure accumulates
  • Restrict HTTP/2 to authenticated clients where the deployment allows it
bash
# Example H2O configuration snippet reducing HTTP/2 exposure surface
http2-max-concurrent-requests-per-connection: 32
http2-idle-timeout: 10
http2-graceful-shutdown-timeout: 5
max-connections: 1024

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.