Ошибка с PHP mail(): множественные или неверные строки, найденные в дополнительном_header
Внезапно начали получать вышеуказанную ошибку без внесения каких-либо изменений в script.
Хост 1 и 1 (я знаю...)
script все еще отлично работает на другом сервере, и поэтому я подозреваю, что, должно быть, было внесено некоторое изменение конфигурации сервера, хотя хозяева умоляли незнание.
Нет информации о вышеуказанной ошибке вообще в Google, которую я могу найти - есть ли у кого-нибудь идеи? Сервер работает с Apache, если это помогает.
Ответы
Ответ 1
Имела только аналогичная проблема.
Он вышел из синего. Код 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
только для заголовков. Сообщение электронной почты (multipart или нет, с 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/standard/mail.c;h=448013a472a3466245e64b1cb37a9d1b0f7c007e;hp=1ebc8fecb7ef4c266a341cdc701f0686d6482242;hb=9d168b863e007c4e15ebe4d2eecabdf8b0582e30;hpb=eee8b6c33fc968ef8c496db8fb54e8c9d9d5a8f9
Ответ 2
Ни один из вышеперечисленных ответов не решил эту проблему для меня. Итак, я расширил свой поиск до "почты с приложением и сообщениями 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";
}
Мой новый код (полный):
Обратите внимание, что $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";
}
Здесь есть два ключевых изменения. (1) удалил все многочастные вещи из заголовков в $message. (2) удалил весь материал "\ r\n" и добавил код $eol = PHP_EOL;
в код.
Вместе эти изменения позволили мне еще раз отправить HTML-письмо с вложениями.
Ответ 3
Была та же проблема:
Удалили границу мимики и сообщение из заголовка и все сработало.
$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);
Ответ 4
Ни одно из вышеперечисленных исправлений для меня - основная проблема: вы не должны помещать в заголовки ничего, кроме заголовков. В старых сценариях что-то там было. Поэтому переместите любой текст или вложения, которые были добавлены в заголовки в тело сообщения. Имеет смысл.
У этого есть пояснение
(Я думаю, это то же самое решение, что и Фрэнк плюс плюс Davisca "нет двойных новых строк" - но вам нужны удвоенные новые строки для вложений)
Ответ 5
Другой сценарий, который приводит к такой же новой ошибке, заключается в том, что вы не отправляете заголовки в команду "mail". Он использовал просто значение по умолчанию и теперь дает ошибку: "Несколько или неверно сформированные строки в add_header".
Можно исправить, добавив следующее:
$header = "From: ".$from_name." <".$from_mail.">\n";
$header .= "Reply-To: ".$replyto."\n";
$header .= "MIME-Version: 1.0\n";
...
mail($mailto,$subject,$emessage,$header);
Ответ 6
моя версия PHP - 5.4.43,
вероятно, содержит исправленную ошибку # 68776.
googling к той же ошибке показал [http://fossies.org/diffs/php/5.4.42_vs_5.4.43/ext/standard/mail.c-diff.html]
= > Я не могу использовать пустые строки как параметры 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)) {
Ответ 7
Это решит вашу проблему. Я немного изменил код Фрэнка. Этот код будет поддерживать вложение и 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);
Ответ 8
Возможно, вы столкнулись с Ошибка # 69874 Невозможно установить пустые дополнительные_данные для почты(), если вы не сделали ничего глупого (т.е. забыл санировать заголовки).
Тест на ошибку
$ 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
Альтернативно, если вы знаете свою версию PHP (подсказка: php -v
), вы можете проверить журнал изменений для номера ошибки (69874), чтобы увидеть ли исправление было применено для вашей версии.
Кратковременное исправление заключается в замене вызовов на почту() следующим образом
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 );
}
Ответ 9
Возможно, кто-то пытается использовать ваш код для ввода заголовков электронной почты.
http://resources.infosecinstitute.com/email-injection/
Я предлагаю вам изучить журналы доступа и т.д. и искать необычную активность. Факт, что вы получаете сообщения об ошибках, надеюсь, означает, что ваш script не был скомпрометирован, и вместо этого это ошибка. Вы должны убедиться, хотя.