From b6564803b699e5900538751d6d19531d5242df91 Mon Sep 17 00:00:00 2001 From: Arturo Bernal Date: Sun, 22 Feb 2026 12:03:02 +0100 Subject: [PATCH] HTTP/2: validate HEADERS PRIORITY payload length Reject incoming HEADERS frames with the PRIORITY flag set but without the mandatory 5-byte priority fields, mapping the condition to a FRAME_SIZE_ERROR instead of allowing a BufferUnderflowException. --- .../impl/nio/AbstractH2StreamMultiplexer.java | 3 +++ .../nio/TestAbstractH2StreamMultiplexer.java | 26 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2StreamMultiplexer.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2StreamMultiplexer.java index 3bb73c7b1..fb9a07795 100644 --- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2StreamMultiplexer.java +++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2StreamMultiplexer.java @@ -1172,6 +1172,9 @@ private void consumeHeaderFrame(final RawFrame frame, final H2Stream stream) thr } final ByteBuffer payload = frame.getPayloadContent(); if (frame.isFlagSet(FrameFlag.PRIORITY)) { + if (payload == null || payload.remaining() < 5) { + throw new H2ConnectionException(H2Error.FRAME_SIZE_ERROR, "Invalid HEADERS priority payload"); + } payload.getInt(); payload.get(); } diff --git a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/nio/TestAbstractH2StreamMultiplexer.java b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/nio/TestAbstractH2StreamMultiplexer.java index 58160ae45..5bb59e541 100644 --- a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/nio/TestAbstractH2StreamMultiplexer.java +++ b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/nio/TestAbstractH2StreamMultiplexer.java @@ -1863,4 +1863,30 @@ void testWindowUpdateZeroIncrementOnStreamIsStreamError() throws Exception { Assertions.assertEquals(H2Error.PROTOCOL_ERROR, H2Error.getByCode(((H2StreamResetException) cause).getCode())); } + @Test + void testHeadersWithPriorityFlagAndShortPayloadRejected() throws Exception { + final AbstractH2StreamMultiplexer mux = new H2StreamMultiplexerImpl( + protocolIOSession, + FRAME_FACTORY, + StreamIdGenerator.ODD, + httpProcessor, + CharCodingConfig.DEFAULT, + H2Config.custom().build(), + h2StreamListener, + () -> streamHandler); + + final RawFrame headers = new RawFrame( + FrameType.HEADERS.getValue(), + FrameFlag.PRIORITY.getValue() | FrameFlag.END_HEADERS.getValue(), + 2, + ByteBuffer.allocate(0)); + + final H2ConnectionException ex = Assertions.assertThrows( + H2ConnectionException.class, + () -> mux.onInput(ByteBuffer.wrap(encodeFrame(headers)))); + + Assertions.assertEquals(H2Error.FRAME_SIZE_ERROR, H2Error.getByCode(ex.getCode())); + } + + } \ No newline at end of file