你能告诉我如何在不丢失原始消息数据的情况下防止PHP 中的电子邮件注入吗?mail()
例如,如果我需要允许用户使用\r\n
,To
等CC
,所以我不想将它们从消息中完全剥离 - 我仍然希望它们被传递,但不添加任何额外的标题或以某种方式允许邮件注入发生。
互联网上的大多数建议都建议完全删除这些数据 - 但我不想这样做。
我通过 PHPmail()
函数发送纯文本(非 HTML)消息。
你有什么建议?
要过滤在收件人电子邮件字段中使用的有效电子邮件,请查看filter_var()
:
$email = filter_var($_POST['recipient_email'], FILTER_VALIDATE_EMAIL);
if ($email === FALSE) {
echo 'Invalid email';
exit(1);
}
这将确保您的用户只提供单个有效的电子邮件,然后您可以将其传递给该mail()
函数。据我所知,没有办法使用 PHPmail()
函数通过消息体注入标头,因此数据不需要任何特殊处理。
更新:
根据文档mail()
,当它直接与 SMTP 服务器通信时,您需要防止消息正文中的句号:
$body = str_replace("\n.", "\n..", $body);
更新#2:
显然,也可以通过主题注入,但是由于没有FILTER_VALIDATE_EMAIL_SUBJECT
,您需要自己进行过滤:
$subject = str_ireplace(array("\r", "\n", '%0A', '%0D'), '', $_POST['subject']);
假设您想将访问者的电子邮件地址放在可选的标题字段中,如下所示:
$headers = "From: $visitorEmailAddress";
然而,如果
$访问者电子邮件地址
包含
“地址@email.com\n\n密件抄送:spam@v1agra.com”
你让自己成为垃圾邮件主机,为邮件注入打开了大门。这是一个非常简单的示例,但有创意的垃圾邮件发送者和恶意黑客可能会在您的电子邮件中潜入具有潜在破坏性的脚本,因为电子邮件是作为纯文本文件发送的。甚至附件也被转换为纯文本,并且它们可以通过添加 mimetype 内容行轻松发送附件。
如果您对 FROM 和/或 TO 字段的表单验证没问题,您必须查看电子邮件正文的表单验证。我会去掉 '-=' 和 '=-' 字符,并防止用户使用strip_tags()
.
试试这个以查看各种选项:
http://www.codeproject.com/Articles/428076/PHP-Mail-Injection-Protection-and-E-Mail-Validatio
它涵盖了几个选项,并试图解释每个选项的好处和风险。
使用指定的 mime 电子邮件库,例如Mail_Mime
:
<?php
include 'Mail.php';
include 'Mail/mime.php' ;
$mime = new Mail_mime();
$mime->setTXTBody("Message goes here");
$hdrs = $mime->headers(array(
'From' => 'you@yourdomain.com',
'Subject' => 'Test mime message'
));
$body = $mime->get();
$mail = &Mail::factory('mail');
$mail->send('postmaster@localhost', $hdrs, $body);
?>