From 62d979cdec39e84979891a0c1d88045f399cd650 Mon Sep 17 00:00:00 2001 From: "Christopher L. Shannon" Date: Thu, 11 Jun 2026 19:44:24 -0400 Subject: [PATCH] Validate Stomp headers against max frame size (#2104) Updates Stomp codec to check headers against max frame size during reading of the headers and not after when reading the body. (cherry picked from commit 7cb413bc3175cc04a6d21228f049ab258b24833a) --- .../activemq/transport/stomp/StompCodec.java | 9 +++++++++ .../transport/stomp/StompMaxFrameSizeTest.java | 14 +++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/activemq-stomp/src/main/java/org/apache/activemq/transport/stomp/StompCodec.java b/activemq-stomp/src/main/java/org/apache/activemq/transport/stomp/StompCodec.java index dd0f48f5aa1..cb89eb45213 100644 --- a/activemq-stomp/src/main/java/org/apache/activemq/transport/stomp/StompCodec.java +++ b/activemq-stomp/src/main/java/org/apache/activemq/transport/stomp/StompCodec.java @@ -67,6 +67,15 @@ public void parse(ByteArrayInputStream input, int readSize) throws Exception { } currentCommand.write(b); + + if (currentCommand.size() > wireFormat.getMaxFrameSize()) { + StompFrameError errorFrame = new StompFrameError( + new ProtocolException("The maximum frame size was exceeded while processing headers.", true)); + errorFrame.setAction(this.action); + transport.doConsume(errorFrame); + return; + } + // end of headers section, parse action and header if (b == '\n' && (previousByte == '\n' || currentCommand.endsWith(crlfcrlf))) { DataByteArrayInputStream data = new DataByteArrayInputStream(currentCommand.toByteArray()); diff --git a/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/StompMaxFrameSizeTest.java b/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/StompMaxFrameSizeTest.java index 9d4f2e7e931..bb9c18e9cba 100644 --- a/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/StompMaxFrameSizeTest.java +++ b/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/StompMaxFrameSizeTest.java @@ -205,25 +205,25 @@ public void testOversizedActionOnNioSslSocket() throws Exception { @Test(timeout = 60000) public void testOversizedHeadersOnPlainSocket() throws Exception { Assume.assumeTrue(testType == TestType.FRAME_MAX_LESS_THAN_HEADER_MAX); - doTestOversizedHeaders(port, false); + doTestOversizedHeaders(port, false, false); } @Test(timeout = 60000) public void testOversizedHeadersOnNioSocket() throws Exception { Assume.assumeTrue(testType == TestType.FRAME_MAX_LESS_THAN_HEADER_MAX); - doTestOversizedHeaders(nioPort, false); + doTestOversizedHeaders(nioPort, false, true); } @Test(timeout = 60000) public void testOversizedHeadersOnSslSocket() throws Exception { Assume.assumeTrue(testType == TestType.FRAME_MAX_LESS_THAN_HEADER_MAX); - doTestOversizedHeaders(sslPort, true); + doTestOversizedHeaders(sslPort, true, false); } @Test(timeout = 60000) public void testOversizedHeadersOnNioSslSocket() throws Exception { Assume.assumeTrue(testType == TestType.FRAME_MAX_LESS_THAN_HEADER_MAX); - doTestOversizedHeaders(nioSslPort, true); + doTestOversizedHeaders(nioSslPort, true, true); } protected void doTestOversizedAction(int port, boolean useSsl) throws Exception { @@ -242,7 +242,7 @@ protected void doTestOversizedAction(int port, boolean useSsl) throws Exception assertTrue(received.getBody().contains("maximum frame size")); } - protected void doTestOversizedHeaders(int port, boolean useSsl) throws Exception { + protected void doTestOversizedHeaders(int port, boolean useSsl, boolean nio) throws Exception { initializeStomp(port, useSsl); StringBuilder headers = new StringBuilder(maxFrameSize + 100); @@ -259,6 +259,10 @@ protected void doTestOversizedHeaders(int port, boolean useSsl) throws Exception assertNotNull(received); assertEquals("ERROR", received.getAction()); assertTrue(received.getBody().contains("maximum frame size")); + // verify we terminated during header processing and not later during the action + if (nio) { + assertTrue(received.getBody().contains("while processing headers")); + } } protected void doOversizedTestMessage(int port, boolean useSsl, int dataSize) throws Exception {