!12 Fix CVE-2024-21742
From: @starlet-dx Reviewed-by: @caodongxia Signed-off-by: @caodongxia
This commit is contained in:
commit
2bcd6b9ee5
95
CVE-2024-21742-pre.patch
Normal file
95
CVE-2024-21742-pre.patch
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
From 9d0a79dd2382440a2c2c1ceee660eb996643f972 Mon Sep 17 00:00:00 2001
|
||||||
|
From: benwa <btellier@linagora.com>
|
||||||
|
Date: Fri, 9 Mar 2018 14:29:07 +0700
|
||||||
|
Subject: [PATCH] MIME4J-268 DefaultMessageWriter should expose a convenient
|
||||||
|
*asBytes* method
|
||||||
|
|
||||||
|
---
|
||||||
|
.../mime4j/message/DefaultMessageWriter.java | 8 +++
|
||||||
|
.../message/DefaultMessageWriterTest.java | 50 +++++++++++++++++++
|
||||||
|
2 files changed, 58 insertions(+)
|
||||||
|
create mode 100644 dom/src/test/java/org/apache/james/mime4j/message/DefaultMessageWriterTest.java
|
||||||
|
|
||||||
|
diff --git a/dom/src/main/java/org/apache/james/mime4j/message/DefaultMessageWriter.java b/dom/src/main/java/org/apache/james/mime4j/message/DefaultMessageWriter.java
|
||||||
|
index 34890a72..4ce7f7b9 100644
|
||||||
|
--- a/dom/src/main/java/org/apache/james/mime4j/message/DefaultMessageWriter.java
|
||||||
|
+++ b/dom/src/main/java/org/apache/james/mime4j/message/DefaultMessageWriter.java
|
||||||
|
@@ -19,6 +19,7 @@
|
||||||
|
|
||||||
|
package org.apache.james.mime4j.message;
|
||||||
|
|
||||||
|
+import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
@@ -48,6 +49,13 @@ public class DefaultMessageWriter implements MessageWriter {
|
||||||
|
private static final byte[] CRLF = { '\r', '\n' };
|
||||||
|
private static final byte[] DASHES = { '-', '-' };
|
||||||
|
|
||||||
|
+ public static byte[] asBytes(Message message) throws IOException {
|
||||||
|
+ ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||||
|
+ DefaultMessageWriter writer = new DefaultMessageWriter();
|
||||||
|
+ writer.writeMessage(message, buffer);
|
||||||
|
+ return buffer.toByteArray();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* Protected constructor prevents direct instantiation.
|
||||||
|
*/
|
||||||
|
diff --git a/dom/src/test/java/org/apache/james/mime4j/message/DefaultMessageWriterTest.java b/dom/src/test/java/org/apache/james/mime4j/message/DefaultMessageWriterTest.java
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..dece2b50
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/dom/src/test/java/org/apache/james/mime4j/message/DefaultMessageWriterTest.java
|
||||||
|
@@ -0,0 +1,50 @@
|
||||||
|
+/****************************************************************
|
||||||
|
+ * Licensed to the Apache Software Foundation (ASF) under one *
|
||||||
|
+ * or more contributor license agreements. See the NOTICE file *
|
||||||
|
+ * distributed with this work for additional information *
|
||||||
|
+ * regarding copyright ownership. The ASF 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 *
|
||||||
|
+ * *
|
||||||
|
+ * http://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 org.apache.james.mime4j.message;
|
||||||
|
+
|
||||||
|
+import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
+
|
||||||
|
+import org.apache.james.mime4j.Charsets;
|
||||||
|
+import org.apache.james.mime4j.dom.Message;
|
||||||
|
+import org.junit.Test;
|
||||||
|
+
|
||||||
|
+public class DefaultMessageWriterTest {
|
||||||
|
+
|
||||||
|
+ @Test
|
||||||
|
+ public void asBytesShouldSerializeTheMessage() throws Exception {
|
||||||
|
+ byte[] bytes = DefaultMessageWriter.asBytes(
|
||||||
|
+ Message.Builder.of()
|
||||||
|
+ .setBody("this is the body", Charsets.UTF_8)
|
||||||
|
+ .setFrom("sender@localhost")
|
||||||
|
+ .setTo("receiver@localhost")
|
||||||
|
+ .setSubject("Cool subject")
|
||||||
|
+ .build());
|
||||||
|
+
|
||||||
|
+ assertThat(new String(bytes, Charsets.UTF_8.name()))
|
||||||
|
+ .isEqualTo("MIME-Version: 1.0\r\n" +
|
||||||
|
+ "Content-Type: text/plain; charset=UTF-8\r\n" +
|
||||||
|
+ "From: sender@localhost\r\n" +
|
||||||
|
+ "To: receiver@localhost\r\n" +
|
||||||
|
+ "Subject: Cool subject\r\n" +
|
||||||
|
+ "\r\n" +
|
||||||
|
+ "this is the body");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+}
|
||||||
|
\ No newline at end of file
|
||||||
159
CVE-2024-21742.patch
Normal file
159
CVE-2024-21742.patch
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
From 9dec5df2a588fed8027839815daefa79ee66efd1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benoit TELLIER <btellier@linagora.com>
|
||||||
|
Date: Fri, 5 Jan 2024 08:12:54 +0100
|
||||||
|
Subject: [PATCH] [FIX] Prevent header injection with MIME4J DOM (#91)
|
||||||
|
|
||||||
|
---
|
||||||
|
core/pom.xml | 5 +++
|
||||||
|
.../apache/james/mime4j/stream/RawField.java | 23 +++++++++++
|
||||||
|
.../james/mime4j/stream/RawFieldTest.java | 40 +++++++++++++++++--
|
||||||
|
.../message/DefaultMessageWriterTest.java | 11 +++++
|
||||||
|
4 files changed, 76 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/core/pom.xml b/core/pom.xml
|
||||||
|
index 942e3e3..412ad67 100644
|
||||||
|
--- a/core/pom.xml
|
||||||
|
+++ b/core/pom.xml
|
||||||
|
@@ -42,6 +42,11 @@
|
||||||
|
<artifactId>commons-io</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
+ <dependency>
|
||||||
|
+ <groupId>org.assertj</groupId>
|
||||||
|
+ <artifactId>assertj-core</artifactId>
|
||||||
|
+ <scope>test</scope>
|
||||||
|
+ </dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
diff --git a/core/src/main/java/org/apache/james/mime4j/stream/RawField.java b/core/src/main/java/org/apache/james/mime4j/stream/RawField.java
|
||||||
|
index 8bcaa77..03a00dd 100644
|
||||||
|
--- a/core/src/main/java/org/apache/james/mime4j/stream/RawField.java
|
||||||
|
+++ b/core/src/main/java/org/apache/james/mime4j/stream/RawField.java
|
||||||
|
@@ -55,6 +55,29 @@ public final class RawField implements Field {
|
||||||
|
|
||||||
|
public RawField(String name, String body) {
|
||||||
|
this(null, -1, name, body);
|
||||||
|
+
|
||||||
|
+ int pos = 0;
|
||||||
|
+
|
||||||
|
+ while (true) {
|
||||||
|
+ pos = body.indexOf('\r', pos);
|
||||||
|
+ if (pos < 0) {
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ if (pos < body.length() + 2) {
|
||||||
|
+ if (body.charAt(pos + 1) != '\n') {
|
||||||
|
+ throw new IllegalArgumentException("Injection of un-encoded line breaks inside header field could be assimilated to header injection");
|
||||||
|
+ }
|
||||||
|
+ if (pos != body.length() - 2 && !isSpace(body, pos + 2)) {
|
||||||
|
+ throw new IllegalArgumentException("Injection of un-encoded line breaks inside header field could be assimilated to header injection");
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ pos ++;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ private static boolean isSpace(String body, int pos) {
|
||||||
|
+ return body.charAt(pos) == ' '
|
||||||
|
+ || body.charAt(pos) == '\t';
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteSequence getRaw() {
|
||||||
|
diff --git a/core/src/test/java/org/apache/james/mime4j/stream/RawFieldTest.java b/core/src/test/java/org/apache/james/mime4j/stream/RawFieldTest.java
|
||||||
|
index 5a1cc7d..90d8513 100644
|
||||||
|
--- a/core/src/test/java/org/apache/james/mime4j/stream/RawFieldTest.java
|
||||||
|
+++ b/core/src/test/java/org/apache/james/mime4j/stream/RawFieldTest.java
|
||||||
|
@@ -19,6 +19,9 @@
|
||||||
|
|
||||||
|
package org.apache.james.mime4j.stream;
|
||||||
|
|
||||||
|
+import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode;
|
||||||
|
+import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
|
||||||
|
+
|
||||||
|
import junit.framework.Assert;
|
||||||
|
import org.apache.james.mime4j.util.ByteSequence;
|
||||||
|
import org.apache.james.mime4j.util.ContentUtil;
|
||||||
|
@@ -45,11 +48,11 @@ public class RawFieldTest {
|
||||||
|
Assert.assertEquals("stuff", field1.getBody());
|
||||||
|
Assert.assertEquals("raw: stuff", field1.toString());
|
||||||
|
|
||||||
|
- RawField field2 = new RawField("raw", null);
|
||||||
|
+ RawField field2 = new RawField("raw", "any");
|
||||||
|
Assert.assertNull(field2.getRaw());
|
||||||
|
Assert.assertEquals("raw", field2.getName());
|
||||||
|
- Assert.assertEquals(null, field2.getBody());
|
||||||
|
- Assert.assertEquals("raw: ", field2.toString());
|
||||||
|
+ Assert.assertEquals("any", field2.getBody());
|
||||||
|
+ Assert.assertEquals("raw: any", field2.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@@ -63,4 +66,35 @@ public class RawFieldTest {
|
||||||
|
Assert.assertEquals(s, field.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
+ @Test
|
||||||
|
+ public void shouldRejectAmbiguousLineEnding() {
|
||||||
|
+ assertThatThrownBy(() -> new RawField("Name", "Value\r\ncheating")).isInstanceOf(IllegalArgumentException.class);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Test
|
||||||
|
+ public void shouldAcceptCRLFTerminatedHeader() {
|
||||||
|
+ assertThatCode(() -> new RawField("Name", "Value\r\n")).doesNotThrowAnyException();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Test
|
||||||
|
+ public void shouldAcceptTabFolding() {
|
||||||
|
+ assertThatCode(() -> new RawField("Name", "Value\r\n\thello")).doesNotThrowAnyException();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Test
|
||||||
|
+ public void shouldAcceptSpaceFolding() {
|
||||||
|
+ assertThatCode(() -> new RawField("Name", "Value\r\n hello")).doesNotThrowAnyException();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Test
|
||||||
|
+ public void shouldAcceptOnlyDelimiter() {
|
||||||
|
+ assertThatCode(() -> new RawField("Name", "\r\n")).doesNotThrowAnyException();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ @Test
|
||||||
|
+ public void shouldAcceptNoDelimiter() {
|
||||||
|
+ assertThatCode(() -> new RawField("Name", "Value")).doesNotThrowAnyException();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
}
|
||||||
|
diff --git a/dom/src/test/java/org/apache/james/mime4j/message/DefaultMessageWriterTest.java b/dom/src/test/java/org/apache/james/mime4j/message/DefaultMessageWriterTest.java
|
||||||
|
index dece2b5..19eafe2 100644
|
||||||
|
--- a/dom/src/test/java/org/apache/james/mime4j/message/DefaultMessageWriterTest.java
|
||||||
|
+++ b/dom/src/test/java/org/apache/james/mime4j/message/DefaultMessageWriterTest.java
|
||||||
|
@@ -20,6 +20,7 @@
|
||||||
|
package org.apache.james.mime4j.message;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
|
|
||||||
|
import org.apache.james.mime4j.Charsets;
|
||||||
|
import org.apache.james.mime4j.dom.Message;
|
||||||
|
@@ -46,5 +47,15 @@ public class DefaultMessageWriterTest {
|
||||||
|
"\r\n" +
|
||||||
|
"this is the body");
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ @Test
|
||||||
|
+ public void shouldThrowOnHeaderInjectionAttempt() throws Exception {
|
||||||
|
+ Message.Builder builder = Message.Builder.of()
|
||||||
|
+ .setBody("this is the body", Charsets.UTF_8)
|
||||||
|
+ .setFrom("sender@localhost");
|
||||||
|
+
|
||||||
|
+ assertThatThrownBy(() -> builder.setContentTransferEncoding("victim@attacker.com\r\nReply-To: attacker@evil.com"))
|
||||||
|
+ .isInstanceOf(IllegalArgumentException.class);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
}
|
||||||
|
\ No newline at end of file
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -1,10 +1,14 @@
|
|||||||
Name: apache-mime4j
|
Name: apache-mime4j
|
||||||
Version: 0.8.1
|
Version: 0.8.1
|
||||||
Release: 1
|
Release: 2
|
||||||
Summary: Apache JAMES Mime4j
|
Summary: Apache JAMES Mime4j
|
||||||
License: ASL 2.0
|
License: ASL 2.0
|
||||||
URL: http://james.apache.org/mime4j
|
URL: http://james.apache.org/mime4j
|
||||||
Source0: http://archive.apache.org/dist/james/mime4j/0.8.1/james-mime4j-sources-0.8.1.zip
|
Source0: http://archive.apache.org/dist/james/mime4j/0.8.1/james-mime4j-sources-0.8.1.zip
|
||||||
|
# https://github.com/apache/james-mime4j/commit/9d0a79dd2382440a2c2c1ceee660eb996643f972
|
||||||
|
Patch0: CVE-2024-21742-pre.patch
|
||||||
|
# https://github.com/apache/james-mime4j/commit/9dec5df2a588fed8027839815daefa79ee66efd1
|
||||||
|
Patch1: CVE-2024-21742.patch
|
||||||
BuildRequires: maven-local mvn(com.google.guava:guava:18.0) mvn(commons-io:commons-io)
|
BuildRequires: maven-local mvn(com.google.guava:guava:18.0) mvn(commons-io:commons-io)
|
||||||
BuildRequires: mvn(commons-logging:commons-logging) mvn(junit:junit)
|
BuildRequires: mvn(commons-logging:commons-logging) mvn(junit:junit)
|
||||||
BuildRequires: mvn(org.apache:apache:pom:) mvn(org.apache.felix:maven-bundle-plugin)
|
BuildRequires: mvn(org.apache:apache:pom:) mvn(org.apache.felix:maven-bundle-plugin)
|
||||||
@ -20,7 +24,7 @@ Summary: Javadoc for %{name}
|
|||||||
API documentation for %{name}.
|
API documentation for %{name}.
|
||||||
|
|
||||||
%prep
|
%prep
|
||||||
%setup -q -n james-mime4j
|
%autosetup -n james-mime4j -p1
|
||||||
%pom_remove_plugin :apache-rat-plugin
|
%pom_remove_plugin :apache-rat-plugin
|
||||||
%pom_remove_plugin :maven-jar-plugin
|
%pom_remove_plugin :maven-jar-plugin
|
||||||
%pom_disable_module assemble
|
%pom_disable_module assemble
|
||||||
@ -29,7 +33,7 @@ for p in core dom storage; do
|
|||||||
done
|
done
|
||||||
|
|
||||||
%build
|
%build
|
||||||
%mvn_build
|
%mvn_build -f -- -Dsource=8
|
||||||
|
|
||||||
%install
|
%install
|
||||||
%mvn_install
|
%mvn_install
|
||||||
@ -42,5 +46,8 @@ done
|
|||||||
%license LICENSE NOTICE
|
%license LICENSE NOTICE
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Thu Feb 29 2024 yaoxin <yao_xin001@hoperun.com> - 0.8.1-2
|
||||||
|
- Fix CVE-2024-21742
|
||||||
|
|
||||||
* Thu Aug 13 2020 chengzihan <chengzihan2@huawei.com> - 0.8.1-1
|
* Thu Aug 13 2020 chengzihan <chengzihan2@huawei.com> - 0.8.1-1
|
||||||
- Package init
|
- Package init
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user