PHP mail() 错误:在 additional_header 中发现多个或格式错误的换行符
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30887610/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Error with PHP mail(): Multiple or malformed newlines found in additional_header
提问by freestate
Suddenly have started receiving the above error without any changes having been made to the script.
突然开始收到上述错误,而没有对脚本进行任何更改。
Host is 1and1 (I know...)
主机是 1and1(我知道...)
The script still works fine on a different server, and so my suspicion is that there must have been some server config change that has lead to this, although the hosts plead ignorance.
该脚本在不同的服务器上仍然可以正常工作,所以我怀疑一定有一些服务器配置更改导致了这种情况,尽管主机辩称无知。
There's no information on the above error at all in Google that I can find - does anybody have any ideas? Server is running Apache if that helps.
我在 Google 中根本找不到有关上述错误的信息-有人有任何想法吗?如果有帮助,服务器正在运行 Apache。
回答by davisca
Had just the similar problem.
It came out of the blue. No PHP Code was changed.
刚刚有类似的问题。
它突然出现。没有更改 PHP 代码。
What was changed: PHP was upgraded 5.5.25-1 to 5.5.26.
更改内容:PHP 从 5.5.25-1 升级到 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).
PHPmail()
函数中的一个安全风险已被修复,additional_headers
不再允许额外的换行符。因为额外的换行符意味着:现在开始电子邮件消息(我们肯定不希望有人通过标题注入一些换行符,然后是恶意消息)。
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.
以前工作正常的东西,例如在标题后有额外的换行符,甚至将整个消息传递给additional_headers
,将不再起作用。
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 inmessage
argument, not in headers.
- 清理你的标题。
additional_headers
参数中没有多个换行符。这些被视为“多或畸形换行符”:\r\r, \r\0, \r\n\r\n, \n\n, \n\0
。 - 使用
additional_headers
仅头。电子邮件消息(多部分与否,带有 ir 不带附件等)属于message
参数,而不属于标题。
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
PHP 安全错误报告:https: //bugs.php.net/bug.php?
id =68776C 代码差异如何修复:http: //git.php.net/?p =php-src.git;a = blobdiff; F = EXT /标准/ mail.c; H = 448013a472a3466245e64b1cb37a9d1b0f7c007e; HP = 1ebc8fecb7ef4c266a341cdc701f0686d6482242; HB = 9d168b863e007c4e15ebe4d2eecabdf8b0582e30; HPB = eee8b6c33fc968ef8c496db8fb54e8c9d9d5a8f9
回答by seveninstl
None of the above answers solved this problem for me. So, I expanded my search to "mail with attachment and HTML message issues." Piecing together info from a few different posts, I came up with this. It allows for BOTHHTML email and an attachment.
以上答案都没有为我解决这个问题。因此,我将搜索范围扩大到“带有附件和 HTML 邮件问题的邮件”。将几个不同帖子的信息拼凑在一起,我想出了这个。它允许BOTHHTML电子邮件和附件。
My original header code:
我的原始标题代码:
$header = "From: ".$from_name." <".$from_mail.">\r\n";
$header .= "Reply-To: ".$replyto."\r\n";
$header .= "MIME-Version: 1.0\r\n";
$header .= "Content-Type: multipart/mixed; boundary=\"".$uid."\"\r\n";
$header .= "--".$uid."\r\n";
$header .= "Content-Type: text/html; charset=ISO-8859-1\r\n";
$header .= "Content-Transfer-Encoding: 8bit\r\n";
$header .= $body."\r\n";
$header .= "--".$uid."\r\n";
$header .= "Content-Type: application/pdf; name=\"".$filename."\"\r\n";
$header .= "Content-Transfer-Encoding: base64\r\n";
$header .= "Content-Disposition: attachment; filename=\"".$filename."\"\r\n";
$header .= $content."\r\n";
$header .= "--".$uid."--";
if (mail($mail_to, $subject, "", $header))
{
return "mail_success";
}
else
{
return "mail_error";
}
My new code (complete): Note that $body is the HTML that is being assembled by a different function.
我的新代码(完整):请注意,$body 是由不同函数组装的 HTML。
$file = $path.$filename;
$file_size = filesize($file);
$handle = fopen($file, "r");
$content = fread($handle, $file_size);
fclose($handle);
$content = chunk_split(base64_encode($content));
$uid = md5(uniqid(time()));
$name = basename($file);
$eol = PHP_EOL;
// Basic headers
$header = "From: ".$from_name." <".$from_mail.">".$eol;
$header .= "Reply-To: ".$replyto.$eol;
$header .= "MIME-Version: 1.0\r\n";
$header .= "Content-Type: multipart/mixed; boundary=\"".$uid."\"";
// Put everything else in $message
$message = "--".$uid.$eol;
$message .= "Content-Type: text/html; charset=ISO-8859-1".$eol;
$message .= "Content-Transfer-Encoding: 8bit".$eol.$eol;
$message .= $body.$eol;
$message .= "--".$uid.$eol;
$message .= "Content-Type: application/pdf; name=\"".$filename."\"".$eol;
$message .= "Content-Transfer-Encoding: base64".$eol;
$message .= "Content-Disposition: attachment; filename=\"".$filename."\"".$eol;
$message .= $content.$eol;
$message .= "--".$uid."--";
if (mail($mail_to, $subject, $message, $header))
{
return "mail_success";
}
else
{
return "mail_error";
}
Two key changes here. (1) removed all the multi-part stuff from the headers into $message. (2) removed all the "\r\n" stuff and added $eol = PHP_EOL;
to the code.
这里有两个关键变化。(1) 将标题中的所有多部分内容删除到 $message 中。(2) 删除所有 "\r\n" 内容并添加$eol = PHP_EOL;
到代码中。
Together, these changes allowed me to once again send HTML email with attachments.
总之,这些更改使我能够再次发送带有附件的 HTML 电子邮件。
回答by Frank
Had the same problem: Removed the mime boundary and message from the header and all worked.
有同样的问题:从标题中删除了 mime 边界和消息,一切正常。
$header = "From: ".$from_name." <".$from_mail.">\n";
$header .= "Reply-To: ".$replyto."\n";
$header .= "MIME-Version: 1.0\n";
$header .= "Content-Type: multipart/mixed; boundary=\"".$uid."\"\n\n";
$emessage= "--".$uid."\n";
$emessage.= "Content-type:text/plain; charset=iso-8859-1\n";
$emessage.= "Content-Transfer-Encoding: 7bit\n\n";
$emessage .= $message."\n\n";
$emessage.= "--".$uid."\n";
$emessage .= "Content-Type: application/octet-stream; name=\"".$filename."\"\n"; // use different content types here
$emessage .= "Content-Transfer-Encoding: base64\n";
$emessage .= "Content-Disposition: attachment; filename=\"".$filename."\"\n\n";
$emessage .= $content."\n\n";
$emessage .= "--".$uid."--";
mail($mailto,$subject,$emessage,$header);
回答by anoldermark
None of the above fixed it for me - main issue is you must not put anything other than header definitions in headers. Old scripts bunged anything in there. So move any text or attachments that were stuffed in to headers into the message body. Makes sense..
以上都没有为我修复它 - 主要问题是你不能在标题中添加标题定义以外的任何内容。旧脚本在那里塞进了任何东西。因此,将填充到标题中的任何文本或附件移动到邮件正文中。说得通..
This has an explanation
(I guess it's same solution as Frank's above plus Davisca's "no double new lines" - but you needdoubled new lines for attachments)
这有一个解释
(我想它与上面的 Frank 的解决方案相同,加上 Davisca 的“没有双新行” - 但你需要为附件添加双新行)
回答by Atara
my PHP version - 5.4.43, probably contains Fixed bug #68776.
我的 PHP 版本 - 5.4.43,可能包含已修复的错误 #68776。
googling to the same error showed [http://fossies.org/diffs/php/5.4.42_vs_5.4.43/ext/standard/mail.c-diff.html]
谷歌搜索同样的错误显示 [ http://fossies.org/diffs/php/5.4.42_vs_5.4.43/ext/standard/mail.c-diff.html]
=> I cannot use empty strings as mail() parameters.
=> 我不能使用空字符串作为 mail() 参数。
my old code:
我的旧代码:
$headers = 'From: ' . $frm . "\r\n";
$headers .= 'To: ' . $contactEmail . "\r\n";
if ( $flag ) {
$headers .= 'To: ' . $contactEmail2 . "\r\n";
}
$headers .= 'Cc: ' . $contactEmailCc . "\r\n";
$headers .= 'Bcc: ' . $contactEmailBcc . "\r\n";
$headers .= 'Return-Path: ' . $frm . "\r\n";
$headers .= 'MIME-Version: 1.0' ."\r\n";
$headers .= 'Content-Type: text/HTML; charset=ISO-8859-1' . "\r\n";
$headers .= 'Content-Transfer-Encoding: 8bit'. "\n\r\n";
$headers .= $htmlText . "\r\n";
if (!mail('', $strSubject, '', $headers)) { // !!! note the empty parameters.
my new code:
我的新代码:
$headers = 'From: ' . $frm . "\r\n";
// note: no "To: " !!!
$headers .= 'Cc: ' . $contactEmailCc . "\r\n";
$headers .= 'Bcc: ' . $contactEmailBcc . "\r\n";
$headers .= 'Return-Path: ' . $frm . "\r\n";
$headers .= 'MIME-Version: 1.0' ."\r\n";
$headers .= 'Content-Type: text/HTML; charset=ISO-8859-1' . "\r\n";
$headers .= 'Content-Transfer-Encoding: 8bit'. "\n\r\n";
// note: no $htmlText !!!
// note: new parameters:
$mTo = $contactEmail;
if ( $flag ) {
$mTo .= ', ' . $contactEmail2;
}
$mMessage .= $htmlText . "\r\n";
if (!mail($mTo, $strSubject, $mMessage, $headers)) {
回答by Mashpy Rahman
This will solve your problem. I have changed a little bit of Frank's code. This code will support attachment and html.
这将解决您的问题。我改变了一点弗兰克的代码。此代码将支持附件和 html。
<?php
$filename = "certificate.jpg";
$path = "/home/omnibl/subdomains/test/certificate/certimage/";
$file = $path . $filename;
$file_size = filesize($file);
$handle = fopen($file, "r");
$content = fread($handle, $file_size);
fclose($handle);
$content = chunk_split(base64_encode($content));
$uid = md5(uniqid(time()));
$name = basename($file);
$eol = PHP_EOL;
$subject = "Mail Out Certificate";
$message = '<h1>Hi i m mashpy</h1>';
$from_name = "[email protected]";
$from_mail = "[email protected]";
$replyto = "[email protected]";
$mailto = "[email protected]";
$header = "From: " . $from_name . " <" . $from_mail . ">\n";
$header .= "Reply-To: " . $replyto . "\n";
$header .= "MIME-Version: 1.0\n";
$header .= "Content-Type: multipart/mixed; boundary=\"" . $uid . "\"\n\n";
$emessage = "--" . $uid . "\n";
$emessage .= "Content-type:text/html; charset=iso-8859-1\n";
$emessage .= "Content-Transfer-Encoding: 7bit\n\n";
$emessage .= $message . "\n\n";
$emessage .= "--" . $uid . "\n";
$emessage .= "Content-Type: application/octet-stream; name=\"" . $filename . "\"\n"; // use different content types here
$emessage .= "Content-Transfer-Encoding: base64\n";
$emessage .= "Content-Disposition: attachment; filename=\"" . $filename . "\"\n\n";
$emessage .= $content . "\n\n";
$emessage .= "--" . $uid . "--";
mail($mailto, $subject, $emessage, $header);
回答by eyal_katz
Another scenario that brings the same new error is if you are not sending any headers to the "mail" command. It used to just use a default, and now gives the misleading error: "Multiple or malformed newlines found in additional_header".
带来相同新错误的另一种情况是,如果您没有向“mail”命令发送任何标题。它过去只使用默认值,现在给出了误导性错误:“在 additional_header 中发现多个或格式错误的换行符”。
Can be fixed by adding this:
可以通过添加以下内容来修复:
$header = "From: ".$from_name." <".$from_mail.">\n";
$header .= "Reply-To: ".$replyto."\n";
$header .= "MIME-Version: 1.0\n";
...
mail($mailto,$subject,$emessage,$header);
回答by b7kich
You may be running into Bug #69874 Can't set empty additional_headers for mail()if you haven't done anything stupid (i.e. forgot to sanitize the headers).
如果您没有做任何愚蠢的事情(即忘记清理标题),您可能会遇到错误 #69874 无法为 mail() 设置空的 additional_headers。
Test for the bug
测试错误
$ php -d display_errors=1 -d display_startup_errors=1 -d error_reporting=30719 -r 'mail("[email protected]","Subject Here", "Message Here",NULL);'
Warning: mail(): Multiple or malformed newlines found in additional_header in Command line code on line 1
Alternately if you know your PHP version (hint: php -v
) you can check the changelogfor the bug number (69874) to see whether the fixhas been applied for your version.
或者,如果您知道您的 PHP 版本(提示:),php -v
您可以检查错误号 (69874)的更改日志,以查看是否已将修复程序应用于您的版本。
A short-term fix is to replace calls to mail() like this
一个短期的解决方法是像这样替换对 mail() 的调用
function fix_mail( $to , $subject , $message , $additional_headers =NULL, $additional_parameters=NULL ) {
$to=filter_var($to, FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES| FILTER_FLAG_STRIP_LOW| FILTER_FLAG_STRIP_HIGH);
$subject=filter_var($subject, FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES| FILTER_FLAG_STRIP_LOW| FILTER_FLAG_STRIP_HIGH);
if (!$additional_headers)
return mail( $to , $subject , $message );
if (!$additional_parameters)
return mail( $to , $subject , $message , $additional_headers );
return mail( $to , $subject , $message , $additional_headers, $additional_parameters );
}
回答by edmondscommerce
This is quite possibly someone trying to take advantage of your code to inject email headers.
这很可能是有人试图利用您的代码来注入电子邮件标头。
http://resources.infosecinstitute.com/email-injection/
http://resources.infosecinstitute.com/email-injection/
I would suggest you examine access logs etc and look for unusual activity. The fact you are getting error messages hopefully means that your script has not been compromised and it is erroring out instead. You need to make sure though.
我建议您检查访问日志等并寻找异常活动。您收到错误消息的事实希望意味着您的脚本没有受到损害,而是出错了。不过你需要确定一下。