PHP mail()错误:在附加的\u头中发现多个或格式错误的换行符

PHP mail()错误:在附加的\u头中发现多个或格式错误的换行符,php,apache,sendmail,Php,Apache,Sendmail,突然,我开始接收到上面的错误,但没有对脚本进行任何更改 主持人是1和1(我知道…) 该脚本在另一台服务器上仍然可以正常工作,因此我怀疑一定是服务器配置的某些更改导致了这种情况,尽管主机声称不知道 我在谷歌上找不到关于上述错误的任何信息——有人有什么想法吗?如果有帮助,服务器正在运行Apache 这很可能是有人试图利用您的代码插入电子邮件标题 我建议您检查访问日志等,并查找异常活动。希望您收到错误消息的事实意味着您的脚本没有被破坏,而是出错了。但您需要确保。也有同样的问题: 已从标头中删除mim

突然,我开始接收到上面的错误,但没有对脚本进行任何更改

主持人是1和1(我知道…)

该脚本在另一台服务器上仍然可以正常工作,因此我怀疑一定是服务器配置的某些更改导致了这种情况,尽管主机声称不知道


我在谷歌上找不到关于上述错误的任何信息——有人有什么想法吗?如果有帮助,服务器正在运行Apache

这很可能是有人试图利用您的代码插入电子邮件标题

我建议您检查访问日志等,并查找异常活动。希望您收到错误消息的事实意味着您的脚本没有被破坏,而是出错了。但您需要确保。

也有同样的问题: 已从标头中删除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);
$header=“From:”.$From\u name.\n”;
$header.=“回复:”.$replyto.\n”;
$header.=“MIME版本:1.0\n”;
$header.=“内容类型:多部分/混合;边界=\”.$uid.\“\n\n”;
$emessage=“-->$uid.\n”;
$emessage.=“内容类型:文本/普通;字符集=iso-8859-1\n”;
$emessage.=“内容传输编码:7bit\n\n”;
$emessage.=$message.“\n\n”;
$emessage.=“-”$uid.\n”;
$emessage.=“内容类型:应用程序/八位字节流;名称=\”.$filename.\”\n;//在这里使用不同的内容类型
$emessage.=“内容传输编码:base64\n”;
$emessage.=“内容处置:附件;文件名=\”.$filename.\“\n\n”;
$emessage.=$content.“\n\n”;
$emessage.=“--”“$uid.”--”;
邮件($mailto、$subject、$emessage、$header);

也有类似的问题。
这是出乎意料的。没有更改任何PHP代码

更改内容:PHP已从5.5.25-1升级到5.5.26

PHP
mail()
函数中的安全风险已被修复,不允许在
附加的\u标题中添加额外的换行符。因为额外的换行符意味着:现在开始发送电子邮件消息(我们当然不希望有人在邮件头上插入一些换行符,然后是一条邪恶的消息)

以前工作正常的内容,例如,在标题后添加额外的换行符,甚至将整个消息传递给
其他标题
,将不再起作用

解决方案

  • 清理你的标题。
    附加_标题中没有多个换行符
    参数。这些计算为“多行或格式错误的换行”:
    \r\r\0\r\n\r\n\n\n\n\0
  • 仅对标题使用
    附加标题
    。电子邮件消息(是否包含多部分,带有不带附件的ir等)属于
    消息
    参数,而不属于标题
PHP安全漏洞报告:

C代码差异如何修复:

另一种导致相同新错误的情况是,如果您没有向“mail”命令发送任何标题。它过去只使用默认值,现在给出了一个误导性错误:“在附加的_头中发现了多个或格式错误的换行符”

可通过添加以下内容进行修复:

$header = "From: ".$from_name." <".$from_mail.">\n";
$header .= "Reply-To: ".$replyto."\n";
$header .= "MIME-Version: 1.0\n";

...

mail($mailto,$subject,$emessage,$header);
$header=“From:”.$From\u name.\n”;
$header.=“回复:”.$replyto.\n”;
$header.=“MIME版本:1.0\n”;
...
邮件($mailto、$subject、$emessage、$header);
如果您没有做任何愚蠢的事情(例如忘记清理标题),您可能会遇到

测试错误

$ php -d display_errors=1 -d display_startup_errors=1 -d error_reporting=30719 -r 'mail("test@email.com","Subject Here", "Message Here",NULL);'

Warning: mail(): Multiple or malformed newlines found in additional_header in Command line code on line 1
或者,如果您知道您的PHP版本(提示:
PHP-v
),您可以检查错误号(69874)以查看是否已应用于您的版本

一个短期修复方法是替换对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 );
    }

以上这些都没有为我解决问题-主要问题是您不能在标题中放置除标题定义以外的任何内容。旧剧本把什么都塞进去了。因此,将填充到标题中的任何文本或附件移动到邮件正文中。有道理

这有一个
(我想这是与上面Frank的解决方案加上Davisca的“没有两行新行”相同的解决方案-但附件需要两行新行)

我的PHP版本-5.4.43, 可能包含固定错误#68776

用谷歌搜索显示的相同错误[

=>我不能将空字符串用作mail()参数

我的旧代码:

$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.
我的新代码:

$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)) {

以上所有答案都没有解决我的问题。因此,我将搜索范围扩大到“带有附件的邮件和HTML邮件问题”。将几个不同帖子的信息拼凑在一起,我得出了这个结论。它允许HTML电子邮件和附件

我的原始标题代码:

$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";
}
$header=“From:”.$From\u name.\r\n”;
$header.=“回复:”.$replyto.\r\n”;
$header.=“MIME版本:1.0\r\n”;
$header.=“内容类型:多部分/混合;边界=\”.$uid.\“\r\n”;
$header.=“-”$uid.\r\n”;
$header.=“内容类型:text/html;字符集=ISO-8859-1\r\n”;
$header.=“内容传输编码:8位\r\n”;
$header.=$body.“\r\n”;
$header.=“-”$uid.\r\n”;
$header.=“内容类型:应用程序/pdf;名称=\”.$filename.\“\r\n”;
$header.=“内容传输编码:base64\r\n”;
$header.=“内容处置:附件;文件名=\”.$filename.\“\r\n”;
$header.=$content.“\r\n”;
$header.=“--”$uid.--”;
if(邮件($mail_to,$subject,“,$header))
{
返回“邮件成功”;
}
其他的
{
返回“邮件错误”;
}
我的新代码(完整): 请注意,$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";
}
$file=$path.$filename;
$file\u size=文件大小($file);
$handle=fopen($file,“r”);
$content=fread($handle,$file\u size);
fclose($handle);
$content=chunk_split(base64_encode($content));
$uid=md5(uniqid(time());
$name=basename($file);
$eol=PHP\u eol;
//基本标题
$header=“From:”.$From_name.“$eol;
$header.=“回复:”.$replyto.$eol;
$header.=“MIME版本:1.0\r\n”;
$header.=“内容
 <?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 = "mail@example.com";
$from_mail = "mail@example.com";
$replyto   = "mail@example.com";
$mailto    = "mail@example.com";
$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);
     $this->_header_str = str_replace("\r\r","",$this->_header_str);
                    $this->_header_str = str_replace("\r\0","",$this->_header_str);
                    $this->_header_str = str_replace("\r\n\r\n","",$this->_header_str);
                    $this->_header_str = str_replace("\n\n","",$this->_header_str);
                    $this->_header_str = str_replace("\n\0","",$this->_header_str);
 if ( ! mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str, "-f ".$this->clean_email($this->_headers['Return-Path'])))
                            return FALSE;
                    else
                            return TRUE;