Skip to content
This repository has been archived by the owner on Jan 8, 2020. It is now read-only.

Mail header - boundary issue (related to ZF2015-04) #7503

Closed
Qronicle opened this issue May 8, 2015 · 16 comments
Closed

Mail header - boundary issue (related to ZF2015-04) #7503

Qronicle opened this issue May 8, 2015 · 16 comments
Assignees
Milestone

Comments

@Qronicle
Copy link

Qronicle commented May 8, 2015

The ZF2015-04 security fix (2.4.1) has broken my Mail implementation. I'm creating a 'multipart/alternative' MIME part with a boundary setting. (I basically copied the Mail spec of ZF1, since ZF2's impementation had a lot of issues for me)

I'm not really sure on how to set the boundary with the new checks in place.

Relevant snippet:

$mail            = new \Zend\Mail\Message();
$bodyMessage     = new MimeMessage();

$multiPartContentMessage = new MimeMessage();
$multiPartContentMessage->addPart($this->text);
$multiPartContentMessage->addPart($this->html);

$multiPartContentMimePart          = new Part($multiPartContentMessage->generateMessage());
$multiPartContentMimePart->charset = $this->encoding;
// Following line breaks the GenericHeader check
$multiPartContentMimePart->type    = 'multipart/alternative;' . PHP_EOL . ' boundary="' .
    $multiPartContentMessage->getMime()->boundary() . '"';

$bodyMessage->addPart($multiPartContentMimePart);
$mail->getHeaders()->addHeaderLine('Content-Transfer-Encoding', Mime::ENCODING_QUOTEDPRINTABLE);

$mail->setBody($bodyMessage);

Exception thrown on last line of that snippet:

Zend\Mail\Header\Exception\InvalidArgumentException

File:
    project/vendor/zendframework/zendframework/library/Zend/Mail/Header/GenericHeader.php:65

Message:
    Invalid header value detected
@Martin-P
Copy link
Contributor

Martin-P commented May 8, 2015

Please see #7501

@Maks3w Maks3w added the Mail label May 8, 2015
@Maks3w Maks3w self-assigned this May 8, 2015
@Qronicle
Copy link
Author

Qronicle commented May 8, 2015

I'm not sure it is really related. (Although special characters break my implementation as well, but since that was covered already, I didn't mention it.) If it is related, I'm probably not understanding the proposed solution of mime encoding all header values.

My headers, before updating to 2.4.1:

To: =?UTF-8?Q?Ruud=20Seberechts?= <[email protected]>
Subject: =?UTF-8?Q?MyProject=20-=20SomeSubject
X-PHP-Originating-Script: 1060:Sendmail.php
Date: Wed, 06 May 2015 17:03:41 +0200
From: =?UTF-8?Q?MyProject?= <[email protected]>
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0
Content-Type: multipart/alternative;
 boundary="=_39473a9706c84dc5be8905ee7bde0fbf";
 charset="UTF-8"
Content-Transfer-Encoding: 8bit
Content-Transfer-Encoding: quoted-printable
Content-Disposition: =?UTF-8?Q?inline?=

Encoding the content-type header gives something like (if I'm doing it right)

Content-Type: multipart/alternative;
 ="0A boundary=3D"=3D_a131a28da50d3394c25780957e950fe3";
 charset="UTF-8"

And this doesn't work in a lot of mail clients

@Qronicle
Copy link
Author

Qronicle commented May 8, 2015

Using the example in the last post of #7501 it was indeed fixed:

$multiPartContentMimePart->type = Mime::encodeQuotedPrintableHeader('multipart/alternative;' . 
    PHP_EOL . ' boundary="' . $multiPartContentMessage->getMime()->boundary() . '"', 'UTF-8');

I do however still find it strange I receive the header like this in my mailbox (without any quoted-printable encoding), but I don't have time to investigate.

Content-Type: multipart/alternative;
 boundary="=_39473a9706c84dc5be8905ee7bde0fbf";
 charset="UTF-8"

@weierophinney
Copy link
Member

I do however still find it strange I receive the header like this in my mailbox (without any quoted-printable encoding)

That's normal behavior; your mail server and/or mail client performs the decoding for you.

@Qronicle
Copy link
Author

Qronicle commented May 8, 2015

I'm viewing the 'raw source' in Mail (on Mac). Headers like subject are still encoded:

To: =?UTF-8?Q?Ruud=20Seberechts?= <[email protected]>
Subject: =?UTF-8?Q?Mailing=20-=20Test?=
X-PHP-Originating-Script: 1060:Sendmail.php
Date: Fri, 08 May 2015 16:48:10 +0200
From: =?UTF-8?Q?SomeProject?= <[email protected]>
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0
Content-Type: multipart/alternative;
 boundary="=_f58289fb8922fe639bbb4790c317ac98";
 charset="UTF-8"
Content-Transfer-Encoding: 8bit
Content-Transfer-Encoding: quoted-printable
Content-Disposition: =?UTF-8?Q?inline?=

So I'm guessing it must be the server :)

@Maks3w
Copy link
Member

Maks3w commented May 8, 2015

@Qronicle I've tested your code and I din't see Content-type quoted encoded.

Please attach a Gist with all variables defined.

@Qronicle
Copy link
Author

Qronicle commented May 8, 2015

https://gist.github.com/Qronicle/dbd168d9cb9c84add6b1

It's the complete Mail class and a small send mail script at the bottom. The Mail class is mostly filler except for the send method at the end.
Note that I haven't updated anything for 2.4.1 except the header at line 654

@weierophinney
Copy link
Member

@Qronicle#7506 should fix this for you. You can test it out by doing the following:

$ composer require zendframework/zendframework:dev-master@dev

and then test.

@Qronicle
Copy link
Author

Qronicle commented May 8, 2015

I assume it should resolve my original problem? Because sadly it doesn't :)
To make sure I was using the dev-master version I tried some special characters in the subject, and that does indeed seem to work.

I've updated my gist to the bare minimum: https://gist.github.com/Qronicle/dbd168d9cb9c84add6b1

The HeaderValue::isValid method does not accept the LF character.
The ZF1 Mime Part class explicitly puts an EOL between the type and the boundary. But http://www.w3.org/Protocols/rfc1341/7_2_Multipart.html seems to indicate an EOL character is not necessary. Hmmm.

@weierophinney
Copy link
Member

@Qronicle I think I've found the problem. When we call addHeaderLine() with the boundary, it's using an invalid folding sequence (\n vs the correct \r\n); working on a fix now.

@weierophinney
Copy link
Member

@Qronicle The problem is one of your own making:

You're using PHP_EOL there to create a continuation header line, but it should be "\r\n" instead. When I made that change, it worked as expected. In other words, the fix introduced in 2.4.1 is identifying a problem in your own code.

@Qronicle
Copy link
Author

Qronicle commented May 8, 2015

You are correct indeed.

But I just noticed there is a boundary property on a Mime Part as well, and if I use that, it's still the same problem.

$multiPartContentMimePart           = new Part($multiPartContentMessage->generateMessage());
$multiPartContentMimePart->charset  = 'UTF-8';
$multiPartContentMimePart->type     = 'multipart/alternative';
$multiPartContentMimePart->boundary = $multiPartContentMessage->getMime()->boundary();

Zend\Mime\Mime::LINEEND also seems to be just "\n"

Edit: This was probably the problem you already mentioned :)

@Maks3w Maks3w reopened this May 9, 2015
@Maks3w Maks3w added this to the 2.4.2 milestone May 10, 2015
@weierophinney
Copy link
Member

But I just noticed there is a boundary property on a Mime Part as well, and if I use that, it's still the same problem.

Can you provide a sample that includes how you're using it with Zend\Mail, please?

@Maks3w
Copy link
Member

Maks3w commented May 11, 2015

@weierophinney #7510

@Qronicle
Copy link
Author

To be sure I also updated https://gist.github.com/Qronicle/dbd168d9cb9c84add6b1

weierophinney added a commit to weierophinney/zendframework that referenced this issue May 11, 2015
…ray()

Per the gist provided by @Qronicle, I've created a unit test against
`Zend\Mail\Message`, and a proposed fix.

`Zend\Mime\Part::getHeadersAsArray()` accepts an optional argument, the line
separator sequence. This defaults to `\n`, but for mail messages, should be
`\r\n`. The proposed patch passes that argument when retrieving MIME headers to
include in the mail message.
@weierophinney
Copy link
Member

Alternate patch: #7514

weierophinney added a commit that referenced this issue May 11, 2015
weierophinney added a commit to zendframework/zend-mail that referenced this issue May 14, 2015
…getHeadersAsArray()

Per the gist provided by @Qronicle, I've created a unit test against
`Zend\Mail\Message`, and a proposed fix.

`Zend\Mime\Part::getHeadersAsArray()` accepts an optional argument, the line
separator sequence. This defaults to `\n`, but for mail messages, should be
`\r\n`. The proposed patch passes that argument when retrieving MIME headers to
include in the mail message.
weierophinney added a commit to zendframework/zend-mail that referenced this issue May 14, 2015
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants