我正在为一个网站构建一个简单的联系表单。它不连接到数据库,它只是发送电子邮件。此代码是否会阻止垃圾邮件发送者使用标头注入?是否有任何我没有看到的漏洞?<?php
//create short variable names
$name= filter_var($_POST['Name'],FILTER_SANITIZE_STRING);
$email= filter_var($_POST['Email'], FILTER_VALIDATE_EMAIL);
$subject= filter_var($_POST['Subject'],FILTER_SANITIZE_STRING);
$message= filter_var($_POST['Message'],FILTER_SANITIZE_STRING);
//set up some static information
$toaddress = 'blah@localhost.com,blahblah@localhost.com';
$mailcontent = "Customer name: ".$name."'n".
"Customer email: ".$email."'n".
"Subject: ".$subject."'n'n".
$message;
$fromaddress = "From:" . $email;
//invoke mail() function to send mail
mail($toaddress, "Website Contact Form",$mailcontent, $fromaddress);
?>
标头注入依赖于能够在标头变量中插入其他换行符,这使得字符串看起来像一个新标头。
例如,允许主题值为 Testing'nCc: spamrecipient@example.com'n'nSome body text
将导致邮件头包含:
Subject: Testing
Cc: spamrecipient@example.com
Some body text
也就是说,施虐者不仅添加了额外的收件人,而且还设法提供了自己的正文。
但是,在您的情况下,$toaddress
是恒定的,即使$toaddress
是用户提供的,也应通过mail()
功能正确消毒。
您的主题标题同样恒定
$message
变量是安全的,因为根据定义,它是正文文本,并且仅在实际标头之后发送。
这只剩下$fromaddress
,并且您已经在使用FILTER_VALIDATE_EMAIL
,它也应该拒绝任何带有换行符的内容。
但是,您应该严格检查该测试的结果,如果结果FALSE
,则应中止整个测试。 如果验证失败,那么mail()
会抱怨被给予一个空白的From:
地址,但那里没有标头注入机会。
据我所知,这段代码实际上是安全的。
另外,恕我直言,您不应该从用户提供的电子邮件地址发送电子邮件。 这将违反反垃圾邮件机制,如SPF。
应使用属于您自己的域的常量From:
值。 如果您愿意,可以在Reply-To
标头中使用正确清理的值,以便更轻松地将后续回复转到所需的地址。
我直言,您的代码不安全,因为您错过了'r
和'n
字符。 filter_var()
只杀死那些,如果FILTER_SANITIZE_STRING
与 FILTER_FLAG_STRIP_LOW
一起使用,这也将过滤掉 ASCII 32 以下的任何字符:
$message= filter_var($_POST['Message'],
FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
此外,FILTER_VALIDATE_MAIL
将返回 true 或 false,您也不考虑这些内容。我建议查看这个优秀的filter_var()
来源,因为主要的PHP手册信息非常少。
更新:正如Alnitak指出的那样,通过代码中的'n'n
,这实际上并不重要。
不,这不会净化任何东西。
捏造那个邮件非常非常容易。
我可以在帖子值(您阅读的)中添加任何内容来操作邮件程序。