Skip to content
RESEARCH INDEX BREACHROAD / INTELLIGENCE NOTE

Netty OHTTP: 17 Bytes Can Stall a Gateway and Logs Can Leak HPKE Keys

Six codec-ohttp and Binary HTTP flaws cover parser loops, OOM, off-heap leaks, integer overflow and private HPKE key disclosure through logs.

PUBLIC RESEARCH
AUTHOR
/ CEO Breachroad · OSCP · PNPT
PUBLISHED
20 August 2026
READING TIME
20 min read
TOPIC
Vulnerabilities and CVEs
Netty OHTTP: 17 Bytes Can Stall a Gateway and Logs Can Leak HPKE Keys

GitHub updated a set of reviewed netty-incubator-codec-ohttp advisories on 20 August. Fixes in 0.0.23.Final address several independent problems in Oblivious HTTP and the RFC 9292 Binary HTTP representation. The most vivid lets an unauthenticated message of roughly 17 bytes consume one event-loop thread at 100% CPU. Others permit unbounded buffering, native direct-memory leakage, an exception after integer overflow, or private HPKE key bytes entering logs.

This set demonstrates why cryptography cannot compensate for an unsafe parser. OHTTP encrypts a request to a gateway using its public HPKE configuration. An attacker can build a cryptographically valid envelope whose decrypted contents are a malicious BHTTP frame. The gateway must treat that plaintext as fully hostile input.

CVE-2026-63202: a loop with no progress

BinaryHttpParser#readFieldSection processes a field section. Its loop continues while fieldSectionLength != 0, and forward-progress guarantees were written as Java assert statements. Assertions are normally disabled in production JVMs. If the declared length is smaller than the bytes consumed, the counter can become negative. If readFieldLine() returns null without advancing the buffer, the next iteration sees exactly the same state.

The advisory describes a roughly 17-byte frame that, when wrapped in a valid OHTTP request, permanently pins an event loop. Netty has a small fixed group of I/O threads, often related to CPU count. A handful of parallel requests can occupy the group and stop legitimate traffic until the process restarts.

This is not a large-request attack. An ordinary HTTP body limit does not stop a tight loop over a tiny buffer. The parser must explicitly require progress, reject length overshoot and throw a controlled exception instead of relying on assert.

CVE-2026-61827 and CVE-2026-63124: lengths are commitments

CVE-2026-61827 concerns missing limits for encoded variable field lengths. A remote peer can declare values that cause indefinite buffering and eventual OutOfMemory. A reverse-proxy request limit may reduce some exposure, but the parser itself must cap a declared length before allocation or waiting for more bytes.

CVE-2026-63124 is another infinite loop at a known-length field-section boundary. Operational impact is similar: one channel consumes a thread and repeated requests remove gateway availability. Two separate findings in the same class argue for state-machine and property-based testing across every parser transition rather than another narrow patch.

CVE-2026-61799: a varint larger than an int

RFC 9292 uses variable-length integers. The implementation read an attacker-controlled value into a long but accumulated it into an int. Java compound assignment can narrow the result. A value such as 2³¹ turns a positive offset negative, bypasses a simple comparison and results in ArrayIndexOutOfBoundsException or IndexOutOfBoundsException.

Java prevents native memory corruption here, but a tiny frame can still close channels and sustain denial of service. Correct handling uses checked arithmetic, verifies the range before conversion to int, and emits a controlled CorruptedFrameException or TooLongFrameException.

CVE-2026-54251: direct memory outside the heap

The OHTTP gateway allocates a pooled direct ByteBuf for decrypted plaintext before verifying the AEAD tag. When verification fails, a CryptoException is thrown but the buffer was not released through a finally path. Repeated invalid ciphertexts therefore leak native off-heap memory.

Observability can be deceptive. JVM heap may look acceptable while process RSS or direct-buffer usage grows. Monitor heap and direct memory separately, alongside AEAD failures and rejected-request rate. Restarting restores service only temporarily while the exposed endpoint remains vulnerable.

CVE-2026-61798: private keys in toString()

BoringSSL integration classes held raw HPKE private-key bytes. BoringSSLAsymmetricCipherKeyPair.toString() included the private-key object, whose own string representation rendered the entire array through Arrays.toString(bytes). A separate initialisation error also inserted private bytes in an IllegalArgumentException.

The presence of that method does not prove every key was exposed. An application must log the object or exception. Java logging and telemetry frameworks frequently call toString() automatically, so logs are a credible exposure location. Rotation may be required after upgrading when historical logs contain the material. Backups, APM pipelines and archives also matter because the logged key can outlive the process.

Version scope and update process

The advisories identify BHTTP and HPKE components through 0.0.22.Final and codec-ohttp before 0.0.23.Final. Version 0.0.23.Final contains the fixes. Check the full Maven dependency tree, imported BOMs, shaded JARs and container images instead of only the direct declaration.

A low-level codec upgrade deserves interoperability tests. Cover clients and gateways, known and indeterminate frame lengths, ByteBuf fragmentation, AEAD failure, retry, timeout and malformed-frame behaviour. The safe negative result is a fast, controlled rejection of one request with no persistent CPU or memory growth.

Do not reproduce weaponised frames against production. Version evidence, artifact hashes, vendor regression tests and a safe malformed corpus in an isolated environment provide a proportionate operational check.

Temporary risk reduction

If deployment requires a change window, restrict gateway access, rate-limit sources, cap concurrent connections, shorten timeouts and isolate the process. Those controls may reduce parallel attempts, but they cannot fix one tiny request that spins forever. Orchestration can restart a stuck pod, but an attacker can exhaust the replacement again.

Set direct-memory limits and alerts to make failure observable, while recognising that a low cap can terminate the process sooner. Disable debug logging of cryptographic objects, redact exception content and minimise access to log stores. These are layers around the issue, not substitutes for 0.0.23.Final.

Hunting and telemetry

Look for event-loop threads stuck in BinaryHttpParser.readFieldSection, prolonged single-core saturation, growing pending channels and no progress despite low traffic volume. For native leakage, inspect direct-memory metrics, RSS, allocation failures and clusters of invalid AEAD tags. Repeated bounds exceptions in the decoder are relevant to the integer-overflow path.

For key exposure, search controlled log systems for BoringSSL class names and initialisation error messages without copying discovered material into tickets. If private bytes are present, restrict the evidence, determine the exposure interval, rotate the pair, retire its public configuration and handle archives under the secret-compromise procedure.

Project facts and Breachroad conclusions

The six mechanisms, package ranges, CVSS ratings and 0.0.23.Final fix come from Netty project advisories. They do not report active exploitation. Rotation, off-heap telemetry, staged rollout and negative testing are Breachroad recommendations dependent on deployment architecture.

Secure engineering training helps teams recognise parser and secret boundaries. Web and API penetration testing can validate gateway failure handling in a controlled environment.

Sources

SHARE / COPY