Skip to main content

netty-incubator-codec-ohttp CVE-2026-63202

HIGH
Uncontrolled Resource Consumption (CWE-400)
2026-08-20 https://github.com/netty/netty-incubator-codec-ohttp GHSA-4899-mpch-38p3
7.5
CVSS 3.1 · GitHub Advisory
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Recon
    Retrieve gateway public HPKE key from published config
  2. Delivery
    Craft ~17-byte BHTTP request with understated field-section length
  3. Exploit
    Encrypt payload as valid OHTTP encapsulated request
  4. Install
    Submit to gateway OHTTP endpoint
  5. C2
    Gateway HPKE decryption succeeds, passes plaintext to BinaryHttpParser
  6. Execute
    Infinite loop in readFieldSection pins event-loop thread at 100% CPU
  7. Impact
    Repeat in parallel to exhaust all I/O threads
  8. Step 8
    Gateway fully offline

Vulnerability Assessment

Weakness
CWE
OWASP Top 10:2025
A06:2025 - Insecure Design
ASVS 5.0
V2 - Validation and Business Logic Resource consumption limits
MITRE ATT&CK

1 technique across 1 tactic: Impact

The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up.

Exploitation Conditions

The target must be running a Java application that uses netty-incubator-codec-ohttp or netty-incubator-codec-bhttp to serve OHTTP-encapsulated requests over the network, with OHttpServerCodec active (the default when the library is used for its intended purpose). No authentication is required: OHTTP's protocol design requires gateways to publish their HPKE key configuration so any client can encrypt requests, making the attack surface inherently public-facing. The JVM must be running without the -ea flag, which is the default for all production deployments; running with -ea converts the hang into an AssertionError. Exploitation is bounded to Availability impact only - there is no path to code execution or data exfiltration. The exploit message is only ~17 bytes, so upstream size-based filtering does not limit exploitation. The vulnerability is not reachable from direct HTTP endpoints that do not process OHTTP-encapsulated Binary HTTP messages.

Impact

The CVSS 7.5 vector (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H) accurately maps to real-world exploitation conditions: the attack is network-delivered, requires no authentication, and achieves full availability impact with a single ~17-byte payload. The low attack complexity rating is well-founded - the OHTTP protocol mandates that gateways publish their HPKE key configuration publicly so any client can encrypt requests, which means there is no cryptographic or access-control barrier between an external attacker and the vulnerable parser. EPSS data was not included in the provided intelligence, so exploitation probability cannot be quantified from that signal; however, the documented PoC and precise root-cause analysis suggest the technical bar for exploitation is very low once an attacker identifies a target OHTTP gateway. No CISA KEV listing is present at time of analysis. The niche deployment footprint of this incubator library limits broad exposure, but any organization running an OHTTP gateway or proxy on this library should treat this as urgent: the DoS is persistent (not transient), requires no retries to confirm success, and affects a thread pool that is fixed and small by default. The impact is strictly availability - no confidentiality or integrity loss is possible from this vulnerability class.

Exploit ScenarioDerived

An attacker queries an OHTTP gateway's publicly-accessible key configuration endpoint to retrieve the HPKE public key, then constructs a Binary HTTP request whose declared field-section length byte is set to 0x01 while the actual field line is longer, producing a ~17-byte payload. The attacker encrypts this under the gateway's public key to form a cryptographically valid OHTTP encapsulated request and submits it via a standard HTTP POST; HPKE decryption succeeds on the gateway side and the decrypted plaintext is passed directly to BinaryHttpParser, which enters an infinite loop in readFieldSection and pegs one Netty event-loop thread at 100% CPU indefinitely. Sending a small burst of such requests in parallel - one per event-loop thread, typically 2 × CPU cores - exhausts the entire thread pool within seconds and takes the gateway fully offline until the JVM process is restarted.

This Week Schedule remediation this week. Why: HIGH severity (CVSS 7.0-8.9).
Patch available

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv1 – Aug 20, 2026

CPU-exhaustion denial of service in netty-incubator-codec-ohttp's BinaryHttpParser permanently pins Netty event-loop threads at 100% CPU via an infinite loop in field-section decoding, reachable by any unauthenticated remote attacker. Because OHTTP gateways publish their HPKE public key by design, an attacker can encrypt a crafted ~17-byte Binary HTTP payload as a cryptographically valid OHTTP request, which passes decryption and reaches the vulnerable parser without any authentication barrier. A handful of such requests exhausts the entire fixed-size Netty event-loop thread pool, rendering the gateway or client fully offline until the process is restarted; no public exploit identified at time of analysis, though an empirically-reproduced proof-of-concept is documented in the advisory.

RemediationAI

Upgrade io.netty.incubator:netty-incubator-codec-bhttp and netty-incubator-codec-ohttp to version 0.0.23.Final, confirmed as the fixed release per GitHub Advisory GHSA-4899-mpch-38p3 and the release tag at https://github.com/netty/netty-incubator-codec-ohttp/releases/tag/netty-incubator-codec-parent-ohttp-0.0.23.Final. If an immediate upgrade is not feasible, the most targeted compensating control is per-source-IP connection rate limiting at the load balancer or reverse proxy in front of the OHTTP gateway - this slows the rate at which an attacker can exhaust event-loop threads, though it does not eliminate the vulnerability and sophisticated attackers can work around IP-based throttling using distributed sources. Note that payload size limits are not an effective workaround because the malicious message is only ~17 bytes, well within any practical threshold. Running the JVM with -ea (assertions enabled) will cause the parser to throw an AssertionError at line 624 on a malicious message rather than spinning indefinitely; this converts a persistent CPU-exhaustion DoS into a connection-level error with negligible operational impact, at the cost of a small runtime overhead from assertion evaluation in all code paths. The definitive fix per the advisory is to change the loop condition from != 0 to > 0 and to promote the two assert statements to explicit CorruptedFrameException throws so wire-format invariants are enforced regardless of JVM flags.

Affected Packages

maven io.netty.incubator:netty-incubator-codec-bhttp fix: 0.0.23.Final

Source: OSV (Open Source Vulnerabilities)

Affects your stack

Affects 1 package in maven

Checking this CVE against your own stacks and servers is part of the Basic plan and up.

Technical ContextAI · show details

The vulnerability resides in io.netty.incubator.codec.bhttp.BinaryHttpParser#readFieldSection (BinaryHttpParser.java:619-626), part of the Maven artifact io.netty.incubator:netty-incubator-codec-bhttp. This library implements Binary HTTP message framing per RFC 9292 and is auto-wired into the OHTTP server and client codecs via OHttpRequestResponseContext.ContentDecoder#decodeChunk, which passes decrypted OHTTP payload bytes directly into BinaryHttpParser.parse() with no intervening application code. CWE-835 (Loop with Unreachable Exit Condition) is the primary root cause: the field-section decoding loop uses fieldSectionLength != 0 as its exit condition rather than > 0, so when an attacker-supplied understated declared length causes the counter to overshoot into negative territory, the condition is permanently true. CWE-400 (Uncontrolled Resource Consumption) is the secondary effect: readFieldLine() legitimately returns null and consumes zero bytes on a truncated or over-long field line, meaning the loop re-enters with identical state - a tight CPU-bound busy spin with no allocation and no memory growth. The two Java assert statements at lines 622 and 624 that would have caught null-return and zero-progress conditions are unconditionally stripped by the JVM unless the process is started with -ea, which no production deployment does.

Know when Java gets its next vulnerability

  • Watch products and get an email when something new is published
  • Check this CVE against your own stack and servers
  • Exploit and PoC references, threat intelligence from 22 sources

No credit card · 7-day full trial

Severity by source

GitHub Advisory PRIMARY 7.5 HIGH
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
vuln.today AI 7.5 HIGH

Network-delivered with no authentication barrier due to OHTTP public-key design; single crafted packet achieves permanent thread exhaustion; no confidentiality or integrity impact possible.

3.1 AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
4.0 AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N

Primary rating from GitHub Advisory.

CVSS VectorGitHub Advisory

Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
None
Availability
High

DescriptionGitHub Advisory

BinaryHttpParser: Unauthenticated CPU-exhaustion DoS via infinite loop in field-section decoding

  • ID: BHTTP-LOOP-001
  • Severity: High
  • CVSS v3.1: 7.5 - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
  • CWE: CWE-835 (Loop with Unreachable Exit Condition) - secondary CWE-400 (Uncontrolled Resource Consumption)
  • Affected component: codec-bhttp → io.netty.incubator.codec.bhttp.BinaryHttpParser#readFieldSection, file codec-bhttp/src/main/java/io/netty/incubator/codec/bhttp/BinaryHttpParser.java:619-626
  • Affected version: netty-incubator-codec-ohttp HEAD d3f2b49 (release 0.0.22.Final + 3 commits). The loop has existed since the parser was introduced and is present in the latest code; all published advisory fixes are already applied.
  • Reachable from: io.netty.incubator.codec.ohttp.OHttpRequestResponseContext$ContentDecoder#decodeChunk (codec-ohttp/.../OHttpRequestResponseContext.java:214), i.e. the auto-wired OHTTP server and client codecs.
  • Confidence: High (empirically reproduced hang + thread dump against the unmodified parser).

Summary

BinaryHttpParser decodes Binary HTTP (RFC 9292) messages. An OHTTP gateway/client built on this library feeds the decrypted OHTTP body straight into BinaryHttpParser.parse(...). The field-section decoding loop terminates only on the exact condition fieldSectionLength != 0 and relies on a Java assert to guarantee forward progress. Because (a) the loop counter can be driven negative and (b) readFieldLine(...) legitimately consumes zero bytes and returns null on a truncated/over-long field line, the loop can spin forever. Assertions are disabled in any normal production JVM, so the two assert statements meant to catch this provide no protection.

A single ~17-byte Binary HTTP message - encapsulated by an unauthenticated attacker inside a normal OHTTP request, using the gateway's public key configuration - pins one Netty event-loop thread at 100% CPU permanently. A handful of such requests exhausts the entire event-loop group and takes the OHTTP gateway (or client) fully offline.

Root cause

BinaryHttpParser.java:619-626:

java
HeaderType lastType = HeaderType.PSEUDO_HEADER;
while (fieldSectionLength != 0) {            // 619  - "!= 0", not "> 0"
    int readableBytes = in.readableBytes();
    lastType = readFieldLine(in, headers, lastType, trailers);
    assert lastType != null;                 // 622  - no-op without -ea
    int read = readableBytes - in.readableBytes();
    assert read > 0;                         // 624  - no-op without -ea
    fieldSectionLength -= read;              // 625
}

Two cooperating defects:

  1. Counter can never hit zero. fieldSectionLength is the *declared* field-section byte length read from the wire (line 592). The loop subtracts the bytes each readFieldLine actually consumes. If a field line consumes more bytes than the (attacker-understated) declared length, fieldSectionLength goes negative and != 0 stays true forever.
  2. Zero-progress iterations. readFieldLine (lines 654-707) returns null without consuming any bytes when the remaining buffer cannot hold a complete field line - at lines 656, 664, 670, and 681 (the in.skipBytes(sumBytes) that advances the reader is only reached on the success path, line 705). When it returns null, read == 0, fieldSectionLength is unchanged, and the loop re-enters with identical state - a tight busy spin.

The only constructs that would have stopped either case are the assert statements on lines 622 and 624, which the JVM strips unless started with -ea. Production deployments do not run with assertions enabled.

Reachability (hop-by-hop, every guard resolved)

Attacker model: OHTTP gateways publish their HPKE key configuration so that *any* client can encrypt requests to them. The attacker therefore encrypts a malicious BHTTP body under the gateway's public key - a perfectly valid OHTTP request. HPKE decapsulation succeeds; the plaintext is attacker-chosen.

  1. OHttpServerCodec.decode → OHttpRequestResponseContext.parse → chunk decode → ContentDecoder.decodeChunk.
  2. OHttpRequestResponseContext.java:211 decrypts the chunk into decryptedChunk; line 212 cumulates it; line 214 calls binaryHttpParser.parse(binaryHttpCumulation, completeBodyReceived) - attacker-controlled plaintext, no application code in between.
  3. parse → READ_KNOWN_LENGTH_REQUEST_HEAD → readRequestHead (line 190).
  4. readRequestHead reads the control data, then at lines 445-451 slices all remaining readable bytes as the field section and calls readFieldSection(..., knownLength=true, maxFieldSectionSize).
  5. Inside readFieldSection:
  • Guard checkFieldSectionTooLarge(fieldSectionLength, max) (line 607): bounds only the *declared* length, which the PoC sets to 1. Passes - not a barrier.
  • Guard in.readableBytes() < sumBytes (line 609): sumBytes is built from the *declared* length, also tiny. Passes - not a barrier.
  • Guards assert (lines 622, 624): no-ops in production. Defeated by default.
  • Loop entered → spins forever (defects 1 + 2).

No reachable guard bounds the *actual* consumption or forces progress. maxFieldSectionSize is irrelevant because the declared length is small and the loop is CPU-bound on a fixed, small buffer (no allocation, no memory growth to trip any size cap).

Proof of concept (executed locally, benign liveness oracle)

The real codec-bhttp sources were compiled unmodified against netty 4.1.135.Final (the version pinned in pom.xml). The harness builds a valid known-length BHTTP request whose declared field-section length (0x01) is understated relative to the actual field line, then calls parse(in, true) on a worker thread with a 6-second watchdog. No payload, no side effects - purely a timing/CPU oracle.

Malicious message (17 bytes):

00 01 67 01 68 01 61 01 70 01 01 61 01 62 01 63 01
│  └method g └scheme h └auth a └path p │  └hdr a:b──┘ └ partial line
└ framing 0 (known-length request)     └ declared field-section length = 1

Observed (production default, assertions OFF):

[*] malicious BHTTP bytes (17): 0001670168016101700101610162016301
[!!] HANG CONFIRMED: parse() still running after 6000 ms
[!!] worker thread CPU time: 6029 ms (≈100% of one core => busy spin)
[!!] worker stack (top frames):
        at io.netty.incubator.codec.bhttp.BinaryHttpParser.readFieldSection(BinaryHttpParser.java:626)
        at io.netty.incubator.codec.bhttp.BinaryHttpParser.readRequestHead(BinaryHttpParser.java:451)
        at io.netty.incubator.codec.bhttp.BinaryHttpParser.parse(BinaryHttpParser.java:190)

CPU time ≈ wall time ⇒ a busy spin (RUNNABLE), not a blocked wait.

Controls:

  • Same input with -ea: parse() throws AssertionError at readFieldSection:624 immediately - proving the assertion is the only would-be guard and is absent in production.
  • Well-formed request (declared length matches): parse() returns DefaultBinaryHttpRequest promptly - proving the harness does not hang on valid input.

PoC sources: findings/netty-incubator-codec-ohttp/raw/Poc.java (hang + control 1) and raw/Poc2.java (negative control).

Impact

Unauthenticated, pre-business-logic remote denial of service. Each malicious request permanently consumes one Netty event-loop thread at 100% CPU. Netty event-loop groups have a small fixed thread count (default 2 × cores); a handful of requests exhausts every I/O thread, after which the gateway/client accepts no further connections and serves no traffic - a complete, persistent DoS that survives until process restart. Availability impact High; no confidentiality/integrity impact.

Adversarial re-reading (attempts to refute)

  • *"maxFieldSectionSize caps it."* No - the declared length in the PoC is 1; the cap (line 607) checks the declared value only. The spin happens on a 17-byte buffer with no allocation. Refutation fails.
  • *"An upstream HTTP size limit / HttpObjectAggregator blocks it."* No - the bug is CPU-bound, not memory-bound. The whole malicious message is tiny and well within any size limit. Refutation fails.
  • *"This is just CVE-2024-40642 (absent input validation)."* No - that advisory was about missing validation of method/scheme/authority/path enabling injection; that fix (the ALLOWED_TOKEN/ALLOWED_SCHEME validators, lines 76-122/461-466) is present and unrelated. This is a control-flow/termination defect in field-section length accounting. Distinct class, distinct code.
  • *"The hang might be a harness artifact."* No - the thread dump pinpoints readFieldSection:626; CPU≈wall confirms a spin; the -ea control throws at the exact assert; the well-formed control returns. The hang is for the claimed reason.
  • *"completeBodyReceived must be true."* Not required - the loop is inside readFieldSection, reached via readRequestHead once the control data is present, independent of that flag. The flag only affects a branch taken *after* readRequestHead returns null, which never happens here.

No concrete blocker survived. Verdict: CONFIRMED.

Remediation

  1. Change the loop exit condition to while (fieldSectionLength > 0) so an overshoot (negative counter) terminates.
  2. Treat a null / zero-progress return from readFieldLine while fieldSectionLength > 0 as a hard framing error - throw CorruptedFrameException("truncated or over-long field line") instead of re-looping.
  3. Reject any field line whose consumed byte count would drive fieldSectionLength below 0 (the declared length must be consumed exactly, per RFC 9292 §3.6).
  4. Do not rely on assert for wire-format invariants on attacker-controlled input; assertions are disabled in production. Promote lines 622/624 to explicit exceptions.

Example:

java
while (fieldSectionLength > 0) {
    int readableBytes = in.readableBytes();
    lastType = readFieldLine(in, headers, lastType, trailers);
    int read = readableBytes - in.readableBytes();
    if (lastType == null || read <= 0) {
        throw new CorruptedFrameException("truncated or over-long field line");
    }
    if (read > fieldSectionLength) {
        throw new CorruptedFrameException("field line exceeds declared field-section length");
    }
    fieldSectionLength -= read;
}

Notes

  • The indeterminate-length field-section path (framing indicators 2/3) shares the same loop and the same != 0 / zero-progress structure; the fix above should cover both. A dedicated trace of getIndeterminateLength (lines 538-566) under non-default maxFieldSectionSize is recorded separately as a lead.
  • Default maxFieldSectionSize for the OHTTP codecs is 8 * 1024 (OHttpCodecBuilder.DEFAULT_MAX_FIELD_SECTION_SIZE), and is irrelevant to this CPU-bound spin.

Blast Radius

ecosystem impact
† from your stack dependencies † transitive graph · vuln.today resolves 4-path depth
  • 1 maven packages depend on io.netty.incubator:netty-incubator-codec-bhttp (1 direct, 0 indirect)

Ecosystem-wide dependent count for version 0.0.23.Final.

Executive ViewAI

Why It Matters

netty-incubator-codec-ohttp contains an unauthenticated remote denial-of-service vulnerability (CVE-2026-63202) that exhausts CPU resources and takes OHTTP gateways offline with minimal attacker effort. Deployments relying on OHTTP face immediate service disruption risk, with no vendor patch currently available, requiring urgent network-based protections to prevent outages.

Business Impact: High
Compensating Controls

Network rate limiting and WAF traffic filtering; process or container-level isolation with automatic restart; strict IP whitelisting for OHTTP access; continuous DDoS detection and mitigation; vendor advisory monitoring for patch availability.

Threat Intelligence Overview

Prevalence
Low
experimental OHTTP incubator library, limited production adoption
Threat Intel
1
1 source
Exploit
POC
Public exploit code exists
Data Quality
3 sources
Confidence: Low
NVD CVE.org GHSA GitHub

How this decision was reached

The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.

SignalValue
Severity HIGH
CISA KEV No
Public POC Yes
EPSS N/A
Patch available Yes
Active threat No
Deciding rule
HIGH severity (CVSS 7.0-8.9)
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

SSVC AssessmentENISA

SSVC Decision· derived
Out-of-Cycle
Exploitation· derived
Poc
System Exposure· derived
Open
Automatable· derived
Yes
Human Impact
High

Priority Score

58
Low Medium High Critical
KEV: 0
EPSS: 0
CVSS: +38
PoC: +20
Weaponized: 0
Threat intel: 0
Gov advisory: 0

Attack Technique

Denial of Service attacks render applications or systems unavailable by overwhelming resources or triggering failure conditions.

Affected Products (CPE)GitHub Advisory

pkg:maven/io.netty.incubator:netty-incubator-codec-bhttp

More in Java

View all
CVE-2012-4681 CRITICAL POC
9.8 Aug 28

Oracle Java SE 7 Update 6 and earlier contains multiple sandbox bypass vulnerabilities via the ClassFinder and forName m

CVE-2015-7450 CRITICAL POC
9.8 Jan 02

Remote code execution in IBM Sterling B2B Integrator, Sterling Integrator, and Tivoli Common Reporting allows unauthenti

CVE-2013-2465 CRITICAL POC
9.8 Jun 18

Java Runtime Environment sandbox bypass via incorrect image channel verification in 2D component allows remote unauthent

CVE-2011-3544 CRITICAL POC
9.8 Oct 19

Oracle Java SE JDK/JRE 7 and 6 Update 27 and earlier allows remote code execution with complete system compromise throug

CVE-2010-1871 HIGH POC
8.8 Aug 05

JBoss Seam 2 in Red Hat JBoss EAP 4.3.0 fails to sanitize JBoss Expression Language inputs, allowing remote attackers to

CVE-2012-1723 CRITICAL POC
9.8 Jun 16

Unspecified vulnerability in the Java Runtime Environment (JRE) component in Oracle Java SE 7 update 4 and earlier, 6 up

CVE-2013-0422 CRITICAL POC
9.8 Jan 10

Multiple vulnerabilities in Oracle Java 7 before Update 11 allow remote attackers to execute arbitrary code by (1) using

CVE-2012-0507 CRITICAL POC
9.8 Jun 07

Unspecified vulnerability in the Java Runtime Environment (JRE) component in Oracle Java SE 7 Update 2 and earlier, 6 Up

CVE-2015-4852 CRITICAL POC
9.8 Nov 18

The WLS Security component in Oracle WebLogic Server 10.3.6.0, 12.1.2.0, 12.1.3.0, and 12.2.1.0 allows remote attackers

CVE-2012-5076 CRITICAL POC
9.8 Oct 16

Unspecified vulnerability in the Java Runtime Environment (JRE) component in Oracle Java SE 7 Update 7 and earlier allow

CVE-2017-3066 CRITICAL POC
9.8 Apr 27

Remote unauthenticated attackers can execute arbitrary code on Adobe ColdFusion servers through Java deserialization fla

CVE-2012-0391 CRITICAL POC
9.8 Jan 08

The ExceptionDelegator component in Apache Struts before 2.2.3.1 interprets parameter values as OGNL expressions during

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy