Skip Menu |

This queue is for tickets about the MailTools CPAN distribution.

Report information
The Basics
Id: 113464
Status: resolved
Priority: 0/
Queue: MailTools

People
Owner: Nobody in particular
Requestors: andrew [...] topdog.za.net
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: 2.15



Subject: Mail::Header incorrect decoding
Date: Wed, 30 Mar 2016 23:31:25 +0200
To: bug-MailTools [...] rt.cpan.org
From: Andrew Colin Kissa <andrew [...] topdog.za.net>
Hi Messages containing crafted mime headers do not get decoded correctly allowing for malware loaded attachments to slip through filtering systems. Content-Disposition: attachment; filename="Kebbekus1958_payment_38C587.rar" Content-Type: application/x-rar-compressed; x-unix-mode=0600; name="Kebbekus1958_payment_38C587.rar" Content-Transfer-Encoding: base64 When a message with the above is parsed, the file Kebbekus1958_payment_38C587.rar contains the base64 encoded data instead of the actual RAR file. The proper mime header i believe should be. Content-Disposition: attachment; filename="Kebbekus1958_payment_38C587.rar" Content-Type: application/x-rar-compressed; x-unix-mode=0600; name="Kebbekus1958_payment_38C587.rar" Content-Transfer-Encoding: base64 Because the attachment is not decoded correctly, systems that extract archives to check files inside can be bypassed to deliver malware payloads in the archive attachments. Maintainer of MIME-Tools indicates the issue is in Mail::Header and suggested i report this to the upstream which is MailTools. - Andrew
Download signature.asc
application/pgp-signature 841b

Message body not shown because it is not plain text.

Subject: Re: [rt.cpan.org #113464] Mail::Header incorrect decoding
Date: Wed, 30 Mar 2016 23:54:13 +0200
To: Andrew Colin Kissa via RT <bug-MailTools [...] rt.cpan.org>
From: Mark Overmeer <mark [...] overmeer.net>
* Andrew Colin Kissa via RT (bug-MailTools@rt.cpan.org) [160330 21:32]: Show quoted text
> Wed Mar 30 17:31:48 2016: Request 113464 was acted upon. > Transaction: Ticket created by andrew@topdog.za.net > Queue: MailTools > Subject: Mail::Header incorrect decoding > Requestors: andrew@topdog.za.net > Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=113464 > > > Messages containing crafted mime headers do not get decoded correctly > allowing for malware loaded attachments to slip through filtering systems. > > Content-Disposition: attachment; filename="Kebbekus1958_payment_38C587.rar" > Content-Type: application/x-rar-compressed; x-unix-mode=0600; > name="Kebbekus1958_payment_38C587.rar" > Content-Transfer-Encoding: base64 > > When a message with the above is parsed, the file > Kebbekus1958_payment_38C587.rar > contains the base64 encoded data instead of the actual RAR file.
Yes: Mail::Header is 30 years old, even before MIME was published as RFC. It does not handle Content-Transfer-Encoding. Show quoted text
> The proper mime header i believe should be. > > Content-Disposition: attachment; filename="Kebbekus1958_payment_38C587.rar" > Content-Type: application/x-rar-compressed; x-unix-mode=0600; > name="Kebbekus1958_payment_38C587.rar" > Content-Transfer-Encoding: base64
I do not see the difference. Show quoted text
> Because the attachment is not decoded correctly, systems that extract > archives to check files inside can be bypassed to deliver malware payloads > in the archive attachments.
If the application uses any MailTools component alone, it will not be able to process complex messages. Applications based on MailTools modules need additional logic to look at the MIME headers for additional processing, like base64 decoding. For instance, MIME-Tools logic. Show quoted text
> Maintainer of MIME-Tools indicates the issue is in Mail::Header and > suggested i report this to the upstream which is MailTools.
I see no way to exploit this. Can you detail you someone would be able to use it? I advice everyone not to use this ancient module for process modern emails. There are many very capable alternatives on CPAN, like MailBox. -- Regards, MarkOv ------------------------------------------------------------------------ Mark Overmeer MSc MARKOV Solutions Mark@Overmeer.net solutions@overmeer.net http://Mark.Overmeer.net http://solutions.overmeer.net
Subject: Re: [rt.cpan.org #113464] Mail::Header incorrect decoding
Date: Thu, 31 Mar 2016 00:02:32 +0200
To: bug-MailTools [...] rt.cpan.org
From: Andrew Colin Kissa <andrew [...] topdog.za.net>
On 30 Mar 2016, at 11:54 PM, "Mark Overmeer via RT" <bug-MailTools@rt.cpan.org> wrote: Show quoted text
> I see no way to exploit this. Can you detail you someone would be > able to use it?
It is not an exploit per say, the bug is used to bypass filtering of prohibited attachments, which then reach the end user who may open the attachment and get infected by malware.
Download signature.asc
application/pgp-signature 841b

Message body not shown because it is not plain text.

Subject: Re: [rt.cpan.org #113464] Mail::Header incorrect decoding
Date: Thu, 31 Mar 2016 00:25:33 +0200
To: Andrew Colin Kissa via RT <bug-MailTools [...] rt.cpan.org>
From: Mark Overmeer <mark [...] overmeer.net>
* Andrew Colin Kissa via RT (bug-MailTools@rt.cpan.org) [160330 22:04]: Show quoted text
> Queue: MailTools > Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=113464 > >
> > I see no way to exploit this. Can you detail you someone would be > > able to use it?
> > It is not an exploit per say, the bug is used to bypass filtering > of prohibited attachments, > which then reach the end user who may open the attachment and get > infected by malware.
Why would it by-pass the filters? An application which scans for spam and malware must first prepare the content of the message to make it possible to scan. Well, when that code uses MailTools, it needs to do the base64 decoing itself. If it does not, that application has a bug. It's not MailTools fault if it is used incorrectly. It's a very limited module. So: no, lacking of handling of Content-Transfer-Encoding does not not have any effect on filtering software. -- Regards, MarkOv ------------------------------------------------------------------------ Mark Overmeer MSc MARKOV Solutions Mark@Overmeer.net solutions@overmeer.net http://Mark.Overmeer.net http://solutions.overmeer.net
Subject: Re: [rt.cpan.org #113464] Mail::Header incorrect decoding
Date: Thu, 31 Mar 2016 00:31:17 +0200
To: bug-MailTools [...] rt.cpan.org
From: Andrew Colin Kissa <andrew [...] topdog.za.net>
On 31 Mar 2016, at 12:25 AM, "Mark Overmeer via RT" <bug-MailTools@rt.cpan.org> wrote: Show quoted text
> An application which scans for spam and malware must first prepare the > content of the message to make it possible to scan. Well, when that > code uses MailTools, it needs to do the base64 decoing itself. If it > does not, that application has a bug. It's not MailTools fault if it > is used incorrectly. It's a very limited module.
Thanks, i guess this needs to be fixed in MIME-Tools which is what sub classes MailTools.
Download signature.asc
application/pgp-signature 841b

Message body not shown because it is not plain text.

Subject: Re: [rt.cpan.org #113464] Mail::Header incorrect decoding
Date: Thu, 31 Mar 2016 00:49:35 +0200
To: Andrew Colin Kissa via RT <bug-MailTools [...] rt.cpan.org>
From: Mark Overmeer <mark [...] overmeer.net>
* Andrew Colin Kissa via RT (bug-MailTools@rt.cpan.org) [160330 22:31]: Show quoted text
> Queue: MailTools > Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=113464 > > > Thanks, i guess this needs to be fixed in MIME-Tools which is what > sub classes MailTools.
I have no knowledge about MIME-Tools, but a quick scan shows http://search.cpan.org/~dskoll/MIME-tools-5.507/lib/MIME/Body.pm ### Dump the ENCODED body data to a filehandle: $body->print(\*STDOUT); ### Slurp all the UNENCODED data in, and put it in a scalar: $string = $body->as_string; ### Slurp all the UNENCODED data in, and put it in an array of lines: @lines = $body->as_lines; So, the latted two options are documented to decode base64, and the first is not. It is documented, hence not a bug of the module. -- Regards, MarkOv ------------------------------------------------------------------------ Mark Overmeer MSc MARKOV Solutions Mark@Overmeer.net solutions@overmeer.net http://Mark.Overmeer.net http://solutions.overmeer.net
Hi, No, here's the issue... Mail::Header stops parsing headers if it encounters the line: name="whatever"; because it doesn't match the $FIELD_NAME regex. It should really only stop when it hits a blank line (or have an option to do so.) I don't really know how it can intelligently handle a malformed line in the middle of a bunch of headers. Ignore it, maybe? Report it back somehow? To summarize, when Mail::Header is fed: Content-Disposition: attachment; filename="Kebbekus1958_payment_38C587.rar" Content-Type: application/x-rar-compressed; x-unix-mode=0600; name="Kebbekus1958_payment_38C587.rar" Content-Transfer-Encoding: base64 It stops at the name= line and the only headers we get back are: Content-Disposition: attachment; filename="Kebbekus1958_payment_38C587.rar" Content-Type: application/x-rar-compressed; x-unix-mode=0600; Regards, Dianne.
Subject: Re: [rt.cpan.org #113464] Mail::Header incorrect decoding
Date: Thu, 31 Mar 2016 01:10:01 +0200
To: Dianne Skoll via RT <bug-MailTools [...] rt.cpan.org>
From: Mark Overmeer <mark [...] overmeer.net>
* Dianne Skoll via RT (bug-MailTools@rt.cpan.org) [160330 23:02]: Show quoted text
> Queue: MailTools > Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=113464 > > > No, here's the issue... Mail::Header stops parsing headers if it encounters > the line: > name="whatever"; > > because it doesn't match the $FIELD_NAME regex. It should really > only stop when it hits a blank line (or have an option to do so.) > > I don't really know how it can intelligently handle a malformed line > in the middle of a bunch of headers. Ignore it, maybe? Report it back > somehow?
Ah, that's a clearer report. Usually, you stop when you cannot handle mistakes automatically. Do the other lines end-up in the body? I have no idea about the logic you use around it: there are a many ways. As far as I can see in the code, you get croak "Bad RFC822 field name '$tag'\n"; So, the program needs to eval the header reading, and decide what to do. Probably best to trash the whole message. -- Regards, MarkOv ------------------------------------------------------------------------ Mark Overmeer MSc MARKOV Solutions Mark@Overmeer.net solutions@overmeer.net http://Mark.Overmeer.net http://solutions.overmeer.net
Subject: Re: [rt.cpan.org #113464] Mail::Header incorrect decoding
Date: Fri, 1 Apr 2016 20:14:16 -0700
To: bug-MailTools [...] rt.cpan.org
From: Mark Sapiro <mark [...] msapiro.net>
Subject: Re: [rt.cpan.org #113464] Mail::Header incorrect decoding
To: bug-MailTools [...] rt.cpan.org
From: Mark Sapiro <mark [...] msapiro.net>
Dianne wrote: Show quoted text
> To summarize, when Mail::Header is fed: > > Content-Disposition: attachment; filename="Kebbekus1958_payment_38C587.rar" > Content-Type: application/x-rar-compressed; x-unix-mode=0600; > name="Kebbekus1958_payment_38C587.rar" > Content-Transfer-Encoding: base64 > > It stops at the name= line and the only headers we get back are: > > Content-Disposition: attachment; filename="Kebbekus1958_payment_38C587.rar" > Content-Type: application/x-rar-compressed; x-unix-mode=0600;
Just to add a bit, this issue exists with both the extract method and the read method of Mail::Header. The issue is that the first line encountered which is not a continuation of a folded header (begins with whitespace) or a 'Field-Name:' line stops processing of the headers. RFC 5322, section 2.1 and it's predecessors are clear that only an empty line marks the end of the headers. Granted there are broken agents that may not leave an empty line at the end of the headers, but at least the code could look ahead at the line following the non-whitespace, non-header line and if that is a 'Field-Name:' line, continue processing with it. -- Mark Sapiro <mark@msapiro.net> The highway is for gamblers, San Francisco Bay Area, California better use your sense - B. Dylan
Download signature.asc
application/pgp-signature 181b

Message body not shown because it is not plain text.

From: cpan [...] perl.wizbit.be
Show quoted text
> As far as I can see in the code, you get > > croak "Bad RFC822 field name '$tag'\n"; > > So, the program needs to eval the header reading, and decide what to > do. > Probably best to trash the whole message.
That does not appear to be the case.. Since example code is always clearer: #!/usr/bin/perl use strict; use warnings; use Mail::Header; use File::Temp qw# tempfile #; my $headers = <<EOF; Content-Disposition: inline; filename="testing.txt" Content-Type: text/ascii; x-unix-mode=0600; name="testing.txt" Content-Transfer-Encoding: base64 EOF my ($fh_out, $filename) = tempfile(); print $fh_out $headers; close $fh_out; open my $fh_in, "<", $filename or die "Can't open $filename: $!"; my $obj = Mail::Header->new([ split m/\n/, $headers ]); print "Extract method:\n"; print "---------------\n"; print $obj->as_string, "\n"; print "\n"; print "Read method:\n"; print "------------\n"; my $obj2 = Mail::Header->new($fh_in); print $obj2->as_string, "\n"; __END__ Running this will show: Extract method: --------------- Content-Disposition: inline; filename="testing.txt" Content-Type: text/ascii; x-unix-mode=0600; Read method: ------------ Content-Disposition: inline; filename="testing.txt" Content-Type: text/ascii; x-unix-mode=0600; => No fatal error is given; When this module is used via MIME::Parser: it has extra code to detect that Mail::Header did not consume all input (and thus all headers); it does flag this as an error but in the default configuration it continues processing the message. The body that followed after the above header was base64 encoded, MIME::Parser however will not base64 decode it since the parsed headers do *not* include 'Content-Transfer-Encoding: base64'. Checking with some mail clients: (i.e. mime part with the above headers + base64 encoded content): both Outlook and Thunderbird are forgiving and base64 decodes the attachment anyway.. There is a case to be made to fixing this but I guess there is also a case to be made for not fixing it (since it are not valid headers).. Looking at this from the point of view of a mail filter such as amavisd: it uses MIME::Parser (which then uses Mail::Header) amavisd does check the result of MIME::Parser (which did record the error) and in a default setup it would reject the mail because of the bad header; The bad header check however can be disabled (or address can be white-listed) and if that happens then other features of amavisd will no longer work correctly.. For example: if the attachment is a ZIP archive then it will attempt to extract it but if the headers are mangled then this will not work since the body is still base64 encoded which will make it impossible to extract/check the archive.. (i.e. virus scanning) Possible patch: --- Mail/Header.pm.orig 2016-04-04 12:36:23.000000000 +0200 +++ Mail/Header.pm 2016-04-04 15:20:36.000000000 +0200 @@ -282,9 +282,11 @@ { my ($self, $lines) = @_; $self->empty; - while(@$lines && $lines->[0] =~ /^($FIELD_NAME|From )/o) - { my $tag = $1; - my $line = shift @$lines; + while(@$lines) + { my $line = shift @$lines; + $line =~ /^($FIELD_NAME|From )/o or next; + my $tag = $1; + $line .= shift @$lines while @$lines && $lines->[0] =~ /^[ \t]+/o; @@ -320,10 +322,12 @@ { ($tag, $line) = _fmt_line $self, $tag, $line; _insert $self, $tag, $line, -1 if defined $line; + $line = undef; + $tag = undef; } - defined $ln && $ln =~ /^($FIELD_NAME|From )/o - or last; + defined $ln or last; + $ln =~ /^($FIELD_NAME|From )/o or next; ($tag, $line) = ($1, $ln); } Running with the above script: Extract method: --------------- Content-Disposition: inline; filename="testing.txt" Content-Type: text/ascii; x-unix-mode=0600; Content-Transfer-Encoding: base64 Read method: ------------ Content-Disposition: inline; filename="testing.txt" Content-Type: text/ascii; x-unix-mode=0600; Content-Transfer-Encoding: base64
Subject: Re: [rt.cpan.org #113464] Mail::Header incorrect decoding
Date: Tue, 5 Apr 2016 16:41:27 +0200
To: "cpan [...] perl.wizbit.be via RT" <bug-MailTools [...] rt.cpan.org>
From: Mark Overmeer <mark [...] nluug.nl>
* cpan@perl.wizbit.be via RT (bug-MailTools@rt.cpan.org) [160404 13:41]: Show quoted text
> That does not appear to be the case..
I cannot deny someone who put so much effort in it ;-) Show quoted text
> => No fatal error is given;
_fmt_line does that, but apparently only when the field-name gets accepted first. Show quoted text
> both Outlook and Thunderbird are forgiving and base64 decodes the > attachment anyway..
Wow, that looks to me as a security risk. You cannot expect all virus/spam- filters to do the same. Amavisd should also get this automatic behavior to be safe. Show quoted text
> Possible patch:
Patch applied with small change: Show quoted text
> > @@ -320,10 +322,12 @@ > { ($tag, $line) = _fmt_line $self, $tag, $line; > _insert $self, $tag, $line, -1 > if defined $line; > + $line = undef; > + $tag = undef;
($line, $tag) = (); We could also add the fragment which is incorrectly folder to its field line... but that may have security consequences as well. I think that throwing it away is safer. When you agree, I'll make a release -- Regards, MarkOv ------------------------------------------------------------------------ Mark Overmeer MSc MARKOV Solutions Mark@Overmeer.net solutions@overmeer.net http://Mark.Overmeer.net http://solutions.overmeer.net
From: cpan [...] perl.wizbit.be
Show quoted text
> We could also add the fragment which is incorrectly folder to its field > line... but that may have security consequences as well. I think that > throwing it away is safer. >
I have no real opinion about that; for my use case the fragment is irrelevant so throwing it away is good; adding it to the previous line would also be good.. But thinking about the issue and patch some more: There might be two extra things that need to be considered: a) (ab)using Mail::Header to detect incorrect MIME headers Before the patch Mail::Header would stop processing the input and this made it possible to detect that the headers were not fully correct. Of course this lead to the bug of missing headers. After the patch the valid headers are added (which is good) but there is no indication that some of the content was bogus.. The docs of the module does mention: "Mail::Header does not always follow the RFCs strict enough, ..." So someone using it to check that a message follows the RFCs would already be missing some cases I guess.. I suppose extra code could be added to set a particular flag and/or an extra method to check the value of this flag.. Not sure how good/clean that would be.. b) using Mail::Header on the full mail message When someone uses Mail::Header on the full email message (and not just on the headers) then it would result in a different behaviour.. Consider the code: #!/usr/bin/perl use strict; use warnings; use Mail::Header; use File::Temp qw# tempfile #; my $msg = <<EOF; Subject: foo From: <bar\@bar.bar> Content-Type: text/plain This is the mail body Foo: bar baz EOF my ($fh_out, $filename) = tempfile(); print $fh_out $msg; close $fh_out; open my $fh_in, "<", $filename or die "Can't open $filename: $!"; my @headers = split m/\n/, $msg; my $obj = Mail::Header->new(); $obj->extract(\@headers); print "Extract method (headers):\n"; print "-------------------------\n"; print $obj->as_string, "\n"; print "\n"; print "Extract method (body):\n"; print "----------------------\n"; print join("\n", @headers, ""); print "\n"; print "\n"; print "Read method (headers):\n"; print "----------------------\n"; my $obj2 = Mail::Header->new($fh_in); print $obj2->as_string, "\n"; my $body = do { local $/; <$fh_in> }; $body = "" if not defined $body; print "Read method (body):\n"; print "-------------------\n"; print $body; __END__ Before the patch this would output: Extract method (headers): ------------------------- Subject: foo From: <bar@bar.bar> Content-Type: text/plain Extract method (body): ---------------------- This is the mail body Foo: bar baz Read method (headers): ---------------------- Subject: foo From: <bar@bar.bar> Content-Type: text/plain Read method (body): ------------------- This is the mail body Foo: bar baz After the patch the output would be: Extract method (headers): ------------------------- Subject: foo From: <bar@bar.bar> Content-Type: text/plain Foo: bar Extract method (body): ---------------------- Read method (headers): ---------------------- Subject: foo From: <bar@bar.bar> Content-Type: text/plain Foo: bar Read method (body): ------------------- So for someone (ab)using Mail::Header in that way the patch may break their code... Of course their code is already broken in case there are invalid headers What I do not know: * is there anyone that (ab)uses Mail::Header in such way? * is this behaviour that you want to support/maintain/recommend? * ... A possible 'fix' for it would be to stop at and empty line.. i.e. for the extract method: $line !~ /\A\Z/o or last; $line =~ /^($FIELD_NAME|From )/o or next; my $tag = $1; and for the read method: defined $ln or last; $ln !~ /\A\Z/o or last; $ln =~ /^($FIELD_NAME|From )/o or next; i.e.: * stop on an empty line * skip invalid headers
Subject: Re: [rt.cpan.org #113464] Mail::Header incorrect decoding
Date: Fri, 15 Apr 2016 09:59:32 +0200
To: "cpan [...] perl.wizbit.be via RT" <bug-MailTools [...] rt.cpan.org>
From: Mark Overmeer <mark [...] overmeer.net>
* cpan@perl.wizbit.be via RT (bug-MailTools@rt.cpan.org) [160406 19:39]: Show quoted text
> Queue: MailTools > Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=113464 >
Show quoted text
> There might be two extra things that need to be considered: > a) (ab)using Mail::Header to detect incorrect MIME headers
... Show quoted text
> The docs of the module does mention: > "Mail::Header does not always follow the RFCs strict enough, ..."
There is are a few reasons that there are multiple implementations for email processors. One of the reasons is that not everyone needs the same features. As I explained before: MailTools dates from pre-MIME. That's very old. In the time that attachements were rare and spam volume low. It is only kept because many book show examples with this module You could, for instance, go for the very powerful MailBox suite. That module is maintained to grow and if it does not already fulfil your needs, it probably will get extended. Show quoted text
> b) using Mail::Header on the full mail message
Show quoted text
> So for someone (ab)using Mail::Header in that way the patch may break > their code... > > What I do not know: > * is there anyone that (ab)uses Mail::Header in such way? > * is this behaviour that you want to support/maintain/recommend? > * ...
I think that everyone is using the code that way. It was a serious bug in our change. I am very glad we did not release it yet ;-) I am planning to release the attached version. -- Regards, MarkOv ------------------------------------------------------------------------ Mark Overmeer MSc MARKOV Solutions Mark@Overmeer.net solutions@overmeer.net http://Mark.Overmeer.net http://solutions.overmeer.net
Download MailTools-2.15.tar.gz
application/x-tar-gz 53.8k

Message body not shown because it is not plain text.

From: cpan [...] perl.wizbit.be
Show quoted text
> I think that everyone is using the code that way. It was a serious > bug > in our change. I am very glad we did not release it yet ;-) > I am planning to release the attached version.
I've tested the attached version with my test cases (I'm sure you did the same but can never hurt to double check) and it does produce the expected output.
Subject: Re: [rt.cpan.org #113464] Mail::Header incorrect decoding
Date: Mon, 18 Apr 2016 14:11:44 +0200
To: "cpan [...] perl.wizbit.be via RT" <bug-MailTools [...] rt.cpan.org>
From: Mark Overmeer <solutions [...] overmeer.net>
* cpan@perl.wizbit.be via RT (bug-MailTools@rt.cpan.org) [160416 20:35]: Show quoted text
> Queue: MailTools > Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=113464 > >
> > I think that everyone is using the code that way. It was a serious > > bug > > in our change. I am very glad we did not release it yet ;-) > > I am planning to release the attached version.
> > I've tested the attached version with my test cases (I'm sure you did the same but can never hurt to double check) and it does produce the expected output. >
Release as 2.15 -- Regards, MarkOv ------------------------------------------------------------------------ Mark Overmeer MSc MARKOV Solutions Mark@Overmeer.net solutions@overmeer.net http://Mark.Overmeer.net http://solutions.overmeer.net
This change to 2.15 broke many applications...