This is an automated email from the ASF dual-hosted git repository.
reta pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cxf.git
The following commit(s) were added to refs/heads/main by this push:
new 1f74aa7943b Make sure attachment-max-header-size property is respected
for repeated and multi-line headers (#3425)
1f74aa7943b is described below
commit 1f74aa7943b704532fecdb61190dca87e9b63313
Author: Andriy Redko <[email protected]>
AuthorDate: Tue Sep 1 17:16:37 2026 -0400
Make sure attachment-max-header-size property is respected for repeated and
multi-line headers (#3425)
---
.../cxf/attachment/AttachmentDeserializerUtil.java | 17 +++-
.../cxf/attachment/AttachmentDeserializerTest.java | 92 ++++++++++++++++++++++
2 files changed, 106 insertions(+), 3 deletions(-)
diff --git
a/core/src/main/java/org/apache/cxf/attachment/AttachmentDeserializerUtil.java
b/core/src/main/java/org/apache/cxf/attachment/AttachmentDeserializerUtil.java
index c74d70c2962..155bc4d9597 100644
---
a/core/src/main/java/org/apache/cxf/attachment/AttachmentDeserializerUtil.java
+++
b/core/src/main/java/org/apache/cxf/attachment/AttachmentDeserializerUtil.java
@@ -95,11 +95,17 @@ final class AttachmentDeserializerUtil {
// preserve the line break and append the continuation
buffer.append("\r\n");
buffer.append(b);
+
+ if (buffer.length() > maxHeaderLength) {
+ LOG.fine("The attachment header size has exceeded the
configured parameter: "
+ + maxHeaderLength);
+ throw new HeaderSizeExceededException();
+ }
}
} else {
// if we have a line pending in the buffer, flush it
if (buffer.length() > 0) {
- addHeaderLine(heads, buffer, maxHeadersCount);
+ addHeaderLine(heads, buffer, maxHeadersCount,
maxHeaderLength);
buffer.setLength(0);
}
// add this to the accumulator
@@ -109,7 +115,7 @@ final class AttachmentDeserializerUtil {
// if we have a line pending in the buffer, flush it
if (buffer.length() > 0) {
- addHeaderLine(heads, buffer, maxHeadersCount);
+ addHeaderLine(heads, buffer, maxHeadersCount, maxHeaderLength);
}
return heads;
}
@@ -144,7 +150,7 @@ final class AttachmentDeserializerUtil {
}
private static void addHeaderLine(Map<String, List<String>> heads,
StringBuilder line,
- int maxHeadersCount) throws IOException {
+ int maxHeadersCount, int maxHeaderLength) throws IOException {
// null lines are a nop
final int size = line.length();
if (size == 0) {
@@ -174,6 +180,11 @@ final class AttachmentDeserializerUtil {
throw new IOException("The attachment contains more headers than
are permitted");
}
List<String> v = heads.computeIfAbsent(name, k -> new ArrayList<>(1));
+ final int headerSize = v.stream().mapToInt(String::length).sum();
+ if ((headerSize + value.length()) > maxHeaderLength) {
+ LOG.fine("The attachment header size has exceeded the configured
parameter: " + maxHeaderLength);
+ throw new HeaderSizeExceededException();
+ }
v.add(value);
}
diff --git
a/core/src/test/java/org/apache/cxf/attachment/AttachmentDeserializerTest.java
b/core/src/test/java/org/apache/cxf/attachment/AttachmentDeserializerTest.java
index 9c106da1800..45cc5642616 100644
---
a/core/src/test/java/org/apache/cxf/attachment/AttachmentDeserializerTest.java
+++
b/core/src/test/java/org/apache/cxf/attachment/AttachmentDeserializerTest.java
@@ -30,6 +30,7 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@@ -713,7 +714,98 @@ public class AttachmentDeserializerTest {
assertThrows("Failure expected on too many attachment headers",
IOException.class,
() -> ad.initializeAttachments());
}
+
+ @Test
+ public void testAttachmentHeaderSize() throws Exception {
+ final Random random = new Random();
+
+ StringBuilder sb = new StringBuilder(10000);
+ // Add many attachment headers
+ sb.append("------=_Part_34950_1098328613.1263781527359\n");
+ sb.append("Header:")
+ .append(random.ints('a', 'z')
+ .limit(500)
+ .collect(StringBuilder::new, StringBuilder::appendCodePoint,
StringBuilder::append))
+ .append('\n');
+ sb.append("Content-Type: text/xml; charset=UTF-8\n")
+ .append("Content-Transfer-Encoding: binary\n")
+ .append("Content-Id:
<318731183421.1263781527359.IBM.WEBSERVICES@auhpap02>\n")
+ .append('\n')
+ .append("<envelope/>\n");
+
+ msg = new MessageImpl();
+ msg.setContent(InputStream.class, new
ByteArrayInputStream(sb.toString().getBytes(StandardCharsets.UTF_8)));
+ msg.put(Message.CONTENT_TYPE, "multipart/related");
+ AttachmentDeserializer ad = new AttachmentDeserializer(msg);
+
+ assertThrows("Failure expected large header value",
HeaderSizeExceededException.class,
+ () -> ad.initializeAttachments());
+ }
+
+ @Test
+ public void testAttachmentRepeatedHeaderSize() throws Exception {
+ final Random random = new Random();
+
+ StringBuilder sb = new StringBuilder(10000);
+ // Add many attachment headers
+ sb.append("------=_Part_34950_1098328613.1263781527359\n");
+ sb.append("Header:")
+ .append(random.ints('a', 'z')
+ .limit(200)
+ .collect(StringBuilder::new, StringBuilder::appendCodePoint,
StringBuilder::append))
+ .append('\n');
+ sb.append("Header:")
+ .append(random.ints('a', 'z')
+ .limit(200)
+ .collect(StringBuilder::new, StringBuilder::appendCodePoint,
StringBuilder::append))
+ .append('\n');
+ sb.append("Content-Type: text/xml; charset=UTF-8\n")
+ .append("Content-Transfer-Encoding: binary\n")
+ .append("Content-Id:
<318731183421.1263781527359.IBM.WEBSERVICES@auhpap02>\n")
+ .append('\n')
+ .append("<envelope/>\n");
+
+ msg = new MessageImpl();
+ msg.setContent(InputStream.class, new
ByteArrayInputStream(sb.toString().getBytes(StandardCharsets.UTF_8)));
+ msg.put(Message.CONTENT_TYPE, "multipart/related");
+ AttachmentDeserializer ad = new AttachmentDeserializer(msg);
+
+ assertThrows("Failure expected large header value",
HeaderSizeExceededException.class,
+ () -> ad.initializeAttachments());
+ }
+ @Test
+ public void testAttachmentMultiLineHeaderSize() throws Exception {
+ final Random random = new Random();
+
+ StringBuilder sb = new StringBuilder(10000);
+ // Add many attachment headers
+ sb.append("------=_Part_34950_1098328613.1263781527359\n");
+ sb.append("Header:")
+ .append(random.ints('a', 'z')
+ .limit(200)
+ .collect(StringBuilder::new, StringBuilder::appendCodePoint,
StringBuilder::append))
+ .append('\n')
+ .append('\t')
+ .append(random.ints('a', 'z')
+ .limit(200)
+ .collect(StringBuilder::new, StringBuilder::appendCodePoint,
StringBuilder::append))
+ .append('\n');
+ sb.append("Content-Type: text/xml; charset=UTF-8\n")
+ .append("Content-Transfer-Encoding: binary\n")
+ .append("Content-Id:
<318731183421.1263781527359.IBM.WEBSERVICES@auhpap02>\n")
+ .append('\n')
+ .append("<envelope/>\n");
+
+ msg = new MessageImpl();
+ msg.setContent(InputStream.class, new
ByteArrayInputStream(sb.toString().getBytes(StandardCharsets.UTF_8)));
+ msg.put(Message.CONTENT_TYPE, "multipart/related");
+ AttachmentDeserializer ad = new AttachmentDeserializer(msg);
+
+ assertThrows("Failure expected large header value",
HeaderSizeExceededException.class,
+ () -> ad.initializeAttachments());
+ }
+
@Test
public void testManyAttachmentsDataHandlerIterator() throws Exception {
prepareAttachments();