CVE-2024-4140: Insufficient Information (NVD-CWE-noinfo)
value: An excessive memory use issue (CWE-770) exists in Email-MIME, before version 1.954, which can cause denial of service when parsing multipart MIME messages. The patch set (from 2020 and 2024) limits excessive depth and the total number of parts.
CWE description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
Published: 2024-05-02T20:15Z
Repository: https://github.com/rjbs/Email-MIME
Language: Other
Files changed: xt/stupid-big.t
Commit date: 2020-05-09 14:20:56 -0400
Commit message: hang onto this stupid test for testing

Diff: diff --git a/xt/stupid-big.t b/xt/stupid-big.t
new file mode 100644
index 0000000..bab3402
--- /dev/null
+++ b/xt/stupid-big.t
@@ -0,0 +1,56 @@
+#!perl
+# vim:ft=perl
+use strict;
+use warnings;
+
+use Test::More;
+use Email::MIME;
+
+sub very_deep_email_string {
+  my $depth = $_[0] || 250_000;
+
+  my $str = q{};
+  my $boundary_prefix = "a" x 77;
+  for my $i (1 .. $depth) {
+    my $boundary = sprintf "$boundary_prefix%08x", $i;
+    $str .= "Content-Type: multipart/mixed; boundary=$boundary\n";
+    $str .= "\n";
+    $str .= "--$boundary\n\n";
+  }
+
+  for my $i (reverse(1 .. $depth)) {
+    $str .= sprintf "--${boundary_prefix}%08x--\n\n", $i;
+  }
+
+  return $str;
+}
+
+sub very_attached_email_string {
+  my $parts = $_[0] || 250_000;
+
+  my $str = q{};
+  my $boundary_prefix = "a" x 77;
+  for my $i (1 .. $parts) {
+    my $boundary = sprintf "$boundary_prefix%08x", $i;
+    $str .= "Content-Type: text/plain; boundary=$boundary\n";
+    $str .= "\n";
+    $str .= "--$boundary\n\n";
+    $str .= sprintf "--${boundary_prefix}%08x--\n\n", $i;
+  }
+
+  return $str;
+}
+
+print `ps -o rss -p $$`;
+
+my $VAES = very_attached_email_string;
+warn length($VAES) / 1024;
+my $email = Email::MIME->new($VAES);
+
+print `ps -o rss -p $$`;
+
+# local $Email::MIME::MAX_DEPTH = 2;
+
+$email = Email::MIME->new( very_deep_email_string() );
+
+print `ps -o rss -p $$`;

Fixed code: #!perl
# vim:ft=perl
use strict;
use warnings;

use Test::More;
use Email::MIME;

sub very_deep_email_string {
  my $depth = $_[0] || 250_000;

  my $str = q{};
  my $boundary_prefix = "a" x 77;
  for my $i (1 .. $depth) {
    my $boundary = sprintf "$boundary_prefix%08x", $i;
    $str .= "Content-Type: multipart/mixed; boundary=$boundary\n";
    $str .= "\n";
    $str .= "--$boundary\n\n";
  }

  for my $i (reverse(1 .. $depth)) {
    $str .= sprintf "--${boundary_prefix}%08x--\n\n", $i;
  }

  return $str;
}

sub very_attached_email_string {
  my $parts = $_[0] || 250_000;

  my $str = q{};
  my $boundary_prefix = "a" x 77;
  for my $i (1 .. $parts) {
    my $boundary = sprintf "$boundary_prefix%08x", $i;
    $str .= "Content-Type: text/plain; boundary=$boundary\n";
    $str .= "\n";
    $str .= "--$boundary\n\n";
    $str .= sprintf "--${boundary_prefix}%08x--\n\n", $i;
  }

  return $str;
}

print `ps -o rss -p $$`;

my $VAES = very_attached_email_string;
warn length($VAES) / 1024;
my $email = Email::MIME->new($VAES);

print `ps -o rss -p $$`;

# local $Email::MIME::MAX_DEPTH = 2;

$email = Email::MIME->new( very_deep_email_string() );

print `ps -o rss -p $$`;