Error With PHP Mail(): Multiple or Malformed Newlines Found in Additional_Header

Error with PHP mail(): Multiple or malformed newlines found in additional_header

Had just the similar problem.

It came out of the blue. No PHP Code was changed.

What was changed: PHP was upgraded 5.5.25-1 to 5.5.26.

A security risk in PHP mail() function has been fixed and extra newlines in additional_headers are allowed no more. Because extra newlines mean: now starts the email message (and we surely don't want somebody to inject some newlines through headers followed by an evil message).

What previously have worked fine, e.g. just having extra newlines after headers or even passing the whole message to additional_headers, will function no more.

Solution:

  • Sanitize your headers. No multiple newlines in additional_headers argument. These count as "multiple or malformed newlines": \r\r, \r\0, \r\n\r\n, \n\n, \n\0.
  • Use additional_headers for headers only. Email message (multipart or not, with ir without attachments, etc) belongs in message argument, not in headers.

PHP Security Bug report: https://bugs.php.net/bug.php?id=68776

C Code diff how its fixed: http://git.php.net/?p=php-src.git;a=blobdiff;f=ext/standard/mail.c;h=448013a472a3466245e64b1cb37a9d1b0f7c007e;
hp=1ebc8fecb7ef4c266a341cdc701f0686d6482242;hb=9d168b863e007c4e15ebe4d2eecabdf8b0582e30;
hpb=eee8b6c33fc968ef8c496db8fb54e8c9d9d5a8f9

mail() error in PHP: Multiple or malformed newlines found in additional_header

Your problem is that you're trying to send message body as headers, as mentioned in the comments to your question.

Trying to send MIME mail attachments via mail() is probably considered torture in some countries. There are plenty of libraries to do this for you, I use the PEAR Mail_Mime package.

function mail_attachment($filename, $mailto, $from_mail, $from_name, $replyto, $subject, $message) {
include("Mail.php");
include("Mail/mime.php");
$headers = [
"To"=>$mailto,
"From"=>"$from_name <$from_mail>",
"Reply-To"=>$replyto
"Subject"=>$subject,
"Date"=>date(DATE_RFC822),
];
$msg = new Mail_mime();
$mail =& Mail::factory("smtp");
$msg->setTXTBody($message);
$msg->addAttachment(file_get_contents($filename), "application/pdf", basename($filename), false);
$body = $msg->get();
$headers = $msg->headers($headers);
$mail->send($email_address, $headers, $body);
}

Regex to get string between curly braces

If your string will always be of that format, a regex is overkill:

>>> var g='{getThis}';
>>> g.substring(1,g.length-1)
"getThis"

substring(1 means to start one character in (just past the first {) and ,g.length-1) means to take characters until (but not including) the character at the string length minus one. This works because the position is zero-based, i.e. g.length-1 is the last position.

For readers other than the original poster: If it has to be a regex, use /{([^}]*)}/ if you want to allow empty strings, or /{([^}]+)}/ if you want to only match when there is at least one character between the curly braces. Breakdown:

  • /: start the regex pattern

    • {: a literal curly brace

      • (: start capturing

        • [: start defining a class of characters to capture

          • ^}: "anything other than }"
        • ]: OK, that's our whole class definition
        • *: any number of characters matching that class we just defined
      • ): done capturing
    • }: a literal curly brace must immediately follow what we captured
  • /: end the regex pattern

Multiple or malformed newlines found in additional_header

You're inserting your message into your headers:

$headers .= $message.$el;

so you'll have

From: someone@somewhere.com
blah: blah
Hi mom!
Content-type: blah blah

which is an illegal email.

Send attachments with PHP Mail()?

I agree with @MihaiIorga in the comments – use the PHPMailer script. You sound like you're rejecting it because you want the easier option. Trust me, PHPMailer is the easier option by a very large margin compared to trying to do it yourself with PHP's built-in mail() function. PHP's mail() function really isn't very good.

To use PHPMailer:

  • Download the PHPMailer script from here: http://github.com/PHPMailer/PHPMailer
  • Extract the archive and copy the script's folder to a convenient place in your project.
  • Include the main script file -- require_once('path/to/file/class.phpmailer.php');

Now, sending emails with attachments goes from being insanely difficult to incredibly easy:

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

$email = new PHPMailer();
$email->SetFrom('you@example.com', 'Your Name'); //Name is optional
$email->Subject = 'Message Subject';
$email->Body = $bodytext;
$email->AddAddress( 'destinationaddress@example.com' );

$file_to_attach = 'PATH_OF_YOUR_FILE_HERE';

$email->AddAttachment( $file_to_attach , 'NameOfFile.pdf' );

return $email->Send();

It's just that one line $email->AddAttachment(); -- you couldn't ask for any easier.

If you do it with PHP's mail() function, you'll be writing stacks of code, and you'll probably have lots of really difficult to find bugs.



Related Topics



Leave a reply



Submit