PHP mail()出错:在additional_header中找到多个或格式错误的换行符

fre*_*ate 38 php apache sendmail

突然开始收到上述错误而没有对脚本进行任何更改.

主机是1和1(我知道......)

该脚本在不同的服务器上仍然可以正常工作,所以我怀疑是否必须有一些服务器配置更改导致这一点,尽管主机恳求无知.

我无法在谷歌找到有关上述错误的信息 - 有没有人有任何想法?如果有帮助,服务器正在运行Apache.

dav*_*sca 58

只是有类似的问题.
它突然出现了.没有更改PHP代码.

改变了什么:PHP升级5.5.25-1到5.5.26.

PHP mail()函数中的安全风险已得到修复,并且additional_headers不再允许使用额外的换行符.因为额外的换行意味着:现在启动电子邮件消息(我们当然不希望有人通过标题注入一些新行,然后是恶意消息).

以前工作得很好,例如只是在标题之后有额外的换行符或者甚至将整个消息传递给它additional_headers,将不再起作用.

方案:

  • 清理标题.additional_headers参数中没有多个换行符.这些被视为"多个或格式错误的新行":\r\r, \r\0, \r\n\r\n, \n\n, \n\0.
  • 使用additional_headers仅头.电子邮件消息(多部分或不具有ir,没有附件等)属于message参数,而不是标题.

PHP安全漏洞报告:https://bugs.php.net/bug.php?
id = 68776 C Code diff如何修复:http://git.php.net/? p = php-src.git; a = blobdiff; F = EXT /标准/ mail.c; H = 448013a472a3466245e64b1cb37a9d1b0f7c007e; HP = 1ebc8fecb7ef4c266a341cdc701f0686d6482242; HB = 9d168b863e007c4e15ebe4d2eecabdf8b0582e30; HPB = eee8b6c33fc968ef8c496db8fb54e8c9d9d5a8f9

  • 很好的答案.不幸的是,一些旧的代码在多部分邮件中使用\n \n在额外的标题中.有人能为这种情况提供解决方案吗? (2认同)

sev*_*stl 43

上述答案都没有为我解决这个问题.因此,我将搜索范围扩展为"带附件和HTML邮件问题的邮件".从几个不同的帖子拼凑信息,我想出了这个.它允许BOTH 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";
}
Run Code Online (Sandbox Code Playgroud)

我的新代码(完整):请注意$ 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";
}
Run Code Online (Sandbox Code Playgroud)

这里有两个关键变化.(1)从标题中删除所有多部分内容到$ message.(2)删除所有"\ r \n"内容并添加$eol = PHP_EOL;到代码中.

这些更改一起让我再次发送带附件的HTML电子邮件.

  • 请注意,在内容之前你必须有一个换行符(最后一个标题后面的换行符),它应该是...... $ message.="Content-Disposition:attachment; filename = \"".$ filename."\"".$ eol. $ EOL; $ message.= $ content.$ eol; (4认同)

小智 11

有同样的问题:从标题中删除了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);
Run Code Online (Sandbox Code Playgroud)


ano*_*ark 5

以上都没有为我修复它 - 主要问题是你不能在标题中添加除标题定义以外的任何内容.旧脚本在那里包含任何东西.因此,将填充到标题中的任何文本或附件移动到邮件正文中.说得通..

这有一个解释
(我猜这与Frank上面的解决方案相同,加上Davisca的"没有双重新线" - 但你需要加倍新的附件线)