在邮件之前如何在PHP中清理用户input?

我有一个简单的PHP邮件程序脚本,它从通过POST提交的表单中获取值并将它们邮寄给我:

<?php $to = "me@example.com"; $name = $_POST['name']; $message = $_POST['message']; $email = $_POST['email']; $body = "Person $name submitted a message: $message"; $subject = "A message has been submitted"; $headers = 'From: ' . $email; mail($to, $subject, $body, $headers); header("Location: http://example.com/thanks"); ?> 

我如何清理input?

使用filter_var()清理postvariables。

这里的例子 。 喜欢:

 echo filter_var($_POST['email'], FILTER_SANITIZE_EMAIL); 

由于您不是在这里build立一个SQL查询或任何东西,我可以看到这些input的唯一相关validation是$ _POST [“email”]的电子邮件validation,如果您真的想要在其他字段上使用字母数字filter限制消息可以包含的范围。

要过滤电子邮件地址,只需使用filter_var :

 $email = filter_var($email, FILTER_SANITIZE_EMAIL); 

根据Frank Farmer的build议,您也可以在电子邮件主题中过滤换行符:

 $subject = str_replace(array("\r","\n"),array(" "," "),$subject); 

正如其他人已经指出, filter_var是伟大的。 如果不可用,请将其添加到您的工具箱中。

$headersvariables在安全性方面特别糟糕。 它可以附加到并导致添加欺骗头。 这个称为电子邮件注入的post讨论得很好。

filter_var i很好,但另一种方法来确保某些东西是一个电子邮件地址,而不是坏的是使用isMail()函数。 这里有一个:

 function isEmail($email) { return preg_match('|^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]{2,})+$|i', $email); }; 

所以要使用这个,你可以这样做:

 if (isset($_POST['email']) && isEmail($_POST['email'])) { $email = $_POST['email'] ; } else { // you could halt execution here, set $email to a default email address // display an error, redirect, or some combination here, } 

在手动validation方面,使用substr()限制长度,运行strip_tags()并限制可以放入的内容。

你需要删除$ headers中的用户提供的input中的任何换行符,这些input将传递给mail()(在你的情况下是$ email)! 看电子邮件注入 。

PHP应该负责清理$ to和$ subject,但也有PHP版本的bug(受影响的PHP 4 <= 4.4.6和PHP 5 <= 5.2.1,见MOPB-34-2007 )。

你可以使用上面artlung的回答中的代码来validation电子邮件。

我使用这种代码来防止标题注入..

 // define some mail() header's parts and commonly used spam code to filter using preg_match $match = "/(from\:|to\:|bcc\:|cc\:|content\-type\:|mime\-version\:|subject\:|x\-mailer\:|reply\-to\:|\%0a|\%0b)/i"; // check if any field's value containing the one or more of the code above if (preg_match($match, $name) || preg_match( $match, $message) || preg_match( $match, $email)) { // I use ajax, so I call the string below and send it to js file to check whether the email is failed to send or not echo "failed"; // If you are not using ajax, then you can redirect it with php header function ie: header("Location: http://example.com/anypage/"); // stop the script before it reach or executing the mail function die(); } 

上面的mail()头过滤太严格了,因为有些用户可能在他们的消息中使用过滤的string,而没有任何意图劫持你的电子邮件的forms,所以redirect到一个页面,解释什么样的string不是允许在表格中或在您的表格页面上解释。