VYPR
Medium severityNVD Advisory· Published Jun 4, 2026

CVE-2026-48480

CVE-2026-48480

Description

The netty incubator codec.bhttp is a java language binary http parser. Prior to version 0.0.22.FInal, the codec-ohttp implementation of draft-ietf-ohai-chunked-ohttp does not verify that a cryptographically-signed final chunk was received before the outer HTTP body terminates. An on-path adversary (the OHTTP relay itself, or any MITM on the relay↔gateway or relay↔client transport) can forward a prefix of a legitimate chunked-OHTTP message—cut at a non-final chunk boundary—and close the outer body cleanly, producing no decryption error and no exception in the receiving application. Version 0.0.22.Final fixes the issue.

Affected products

2

Patches

1
28f977f29359

Merge commit from fork

https://github.com/netty/netty-incubator-codec-ohttpNorman MaurerJun 3, 2026via nvd-ref
2 files changed · +82 0
  • codec-ohttp/src/main/java/io/netty/incubator/codec/ohttp/OHttpVersionChunkDraft.java+5 0 modified
    @@ -172,13 +172,18 @@ public void parse(ByteBufAllocator alloc, ByteBuf in, boolean completeBodyReceiv
                     return;
                 }
             }
    +        boolean finalChunk = false;
             while (in.isReadable()) {
                 ChunkInfo chunkInfo = parseNextChunk(in, completeBodyReceived, maxChunkSize);
                 if (chunkInfo == null) {
                     break;
                 }
    +            finalChunk |= chunkInfo.isFinal;
                 decoder.decodeChunk(alloc, in, chunkInfo.length, chunkInfo.isFinal, out);
             }
    +        if (completeBodyReceived && !finalChunk) {
    +            throw new CorruptedFrameException("OHTTP stream ended without a final chunk");
    +        }
         }
     
         @Override
    
  • codec-ohttp/src/test/java/io/netty/incubator/codec/ohttp/OHttpVersionChunkDraftTest.java+77 0 added
    @@ -0,0 +1,77 @@
    +/*
    + * Copyright 2026 The Netty Project
    + *
    + * The Netty Project licenses this file to you under the Apache License,
    + * version 2.0 (the "License"); you may not use this file except in compliance
    + * with the License. You may obtain a copy of the License at:
    + *
    + *   https://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
    + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
    + * License for the specific language governing permissions and limitations
    + * under the License.
    + */
    +package io.netty.incubator.codec.ohttp;
    +
    +import io.netty.buffer.ByteBuf;
    +import io.netty.buffer.ByteBufAllocator;
    +import io.netty.buffer.UnpooledByteBufAllocator;
    +import io.netty.handler.codec.CorruptedFrameException;
    +import io.netty.incubator.codec.bhttp.VarIntCodecUtils;
    +import io.netty.incubator.codec.hpke.CryptoException;
    +import org.junit.jupiter.api.Test;
    +
    +import java.util.ArrayList;
    +import java.util.List;
    +
    +import static org.junit.jupiter.api.Assertions.assertThrows;
    +
    +public class OHttpVersionChunkDraftTest {
    +    private static final OHttpChunkFramer.Decoder NOOP_DECODER = new OHttpChunkFramer.Decoder() {
    +        @Override
    +        public boolean decodePrefix(ByteBufAllocator alloc, ByteBuf in) {
    +            return false;
    +        }
    +
    +        @Override
    +        public boolean isPrefixNeeded() {
    +            return false;
    +        }
    +
    +        @Override
    +        public void decodeChunk(ByteBufAllocator alloc, ByteBuf chunk, int chunkLength,
    +                                boolean completeBodyReceived, List<Object> out) {
    +            // Noop.
    +        }
    +    };
    +
    +    @Test
    +    public void testTruncation() {
    +        ByteBufAllocator alloc = UnpooledByteBufAllocator.DEFAULT;
    +        ByteBuf buf = alloc.buffer();
    +        try {
    +            List<Object> out = new ArrayList<>();
    +            VarIntCodecUtils.writeVariableLengthInteger(buf, 8);
    +            assertThrows(CorruptedFrameException.class, () -> OHttpVersionChunkDraft.INSTANCE.parse(
    +                    alloc, buf, true, NOOP_DECODER, out));
    +        } finally {
    +            buf.release();
    +        }
    +    }
    +
    +    @Test
    +    public void testNoTruncation() throws CryptoException {
    +        ByteBufAllocator alloc = UnpooledByteBufAllocator.DEFAULT;
    +        ByteBuf buf = alloc.buffer();
    +        try {
    +            List<Object> out = new ArrayList<>();
    +            VarIntCodecUtils.writeVariableLengthInteger(buf, 0);
    +            OHttpVersionChunkDraft.INSTANCE.parse(
    +                    alloc, buf, true, NOOP_DECODER, out);
    +        } finally {
    +            buf.release();
    +        }
    +    }
    +}
    

Vulnerability mechanics

Root cause

"The OHTTP parser did not verify that a final chunk was received before the outer HTTP body terminated."

Attack vector

An on-path adversary, such as an OHTTP relay or a man-in-the-middle attacker, can truncate a legitimate chunked OHTTP message before its final chunk. By closing the outer HTTP body cleanly after forwarding this truncated message, the adversary can cause the receiver to process an incomplete message without triggering decryption errors or exceptions. This bypasses the expected security checks for a complete and valid OHTTP message [ref_id=1].

Affected code

The vulnerability exists in the `OHttpVersionChunkDraft.parse` method within the `codec-ohttp` module. Specifically, the logic for processing chunks of an OHTTP message did not adequately check for the termination condition of the final chunk before the outer HTTP body concluded [patch_id=4830358, ref_id=1].

What the fix does

The patch introduces validation to ensure that a final chunk is received before the outer HTTP body is considered complete. A new boolean flag `finalChunk` is used to track if the final chunk has been processed. If the outer body is marked as complete but the `finalChunk` flag is not set, a `CorruptedFrameException` is thrown, preventing the processing of incomplete OHTTP streams [patch_id=4830358, ref_id=1].

Preconditions

  • networkThe attacker must be an on-path adversary, such as an OHTTP relay or a man-in-the-middle attacker.
  • inputThe attacker needs to be able to intercept and forward a prefix of a legitimate chunked OHTTP message.

Reproduction

The patch includes a unit test `OHttpVersionChunkDraftTest.testTruncation` which asserts that a `CorruptedFrameException` is thrown when an OHTTP stream ends without a final chunk, demonstrating the fix for the vulnerability [ref_id=1].

Generated on Jun 4, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

2

News mentions

1