防止 php web 联系表单垃圾邮件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43379125/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Prevent php web contact form spam
提问by user7858610
I am an amateur web designer, I have searched on stackoverflow.com and other websites and have found many fixes for this issue I'm having, but none of them have worked (probably because I implement them incorrectly). I'm hoping someone with more knowledge can help me with a simple fix or show me how to implement one of the fixes I've found.
我是一名业余网页设计师,我在 stackoverflow.com 和其他网站上进行了搜索,并为我遇到的这个问题找到了许多修复程序,但它们都没有奏效(可能是因为我错误地实现了它们)。我希望有更多知识的人可以帮助我进行简单的修复,或者向我展示如何实施我发现的修复之一。
The problem: I have a very simple php contact form on my business's website. It has worked great for years, but in the last week has been hacked. I now receive hundreds of contact form submissions a day with no comments, they only have (apparently valid) email addresses, and a string of characters in the name field (like "58ee8b52eef46").
问题:我的公司网站上有一个非常简单的 php 联系表。它多年来一直运行良好,但在上周被黑客入侵。我现在每天收到数百份联系表单提交,没有任何评论,他们只有(显然有效)电子邮件地址,以及姓名字段中的一串字符(如“58ee8b52eef46”)。
I have tried several techniques to prevent this spam, and they either break my php form, or they don't prevent the spam. If possible I would like a solution that does NOT require a Captcha distorted text test, and does NOT require all fields of the form to be filled.
我尝试了几种技术来防止这种垃圾邮件,它们要么破坏我的 php 表单,要么不能防止垃圾邮件。如果可能,我想要一个不需要验证码扭曲文本测试的解决方案,并且不需要填写表单的所有字段。
Here is my full PHP code:
这是我的完整 PHP 代码:
<?php
if(isset($_POST['email'])) {
$email_to = "[email protected]";
$email_subject = "website form submission";
function died($error) {
echo "We are very sorry, but there were error(s) found with the form you submitted. ";
echo "These errors appear below.<br /><br />";
echo $error."<br /><br />";
echo "Please go back and fix these errors.<br /><br />";
die();
}
if (!isset($_POST['name']) ||
!isset($_POST['email']) ||
!isset($_POST['telephone']) ||
!isset($_POST['comments'])) {
died('We are sorry, but there appears to be a problem with the form you submitted.');
}
$name = $_POST['name'];
$email_from = $_POST['email'];
$telephone = $_POST['telephone'];
$comments = $_POST['comments'];
$error_message = "";
if(strlen($error_message) > 0) {
died($error_message);
}
$email_message = "Form details below.\n\n";
function clean_string($string) {
$bad = array("content-type","bcc:","to:","cc:","href");
return str_replace($bad,"",$string);
}
$email_message .= "Name: ".clean_string($name)."\n";
$email_message .= "Email: ".clean_string($email_from)."\n";
$email_message .= "Telephone: ".clean_string($telephone)."\n";
$email_message .= "Comments: ".clean_string($comments)."\n";
$headers = 'From: '.$email_from."\r\n" .
'Reply-To: '.$email_from."\r\n" .
'X-Mailer: PHP/' . phpversion();
@mail($email_to, $email_subject, $email_message, $headers);
?>
Thank you for contacting us. We will be in touch with you soon. You will now be redirected back to example.com.
<META http-equiv="refresh" content="2;URL=http://www.example.com">
<?php
}
die();
?>
回答by Steve
A simple trick is to create a honeypot field:
一个简单的技巧是创建一个蜜罐字段:
html
html
<!-- within your existing form add this field -->
<input type="text" id="website" name="website"/>
css
css
/*in your css hide the field so real users cant fill it in*/
form #website{ display:none; }
php
php
//in your php ignore any submissions that inlcude this field
if(!empty($_POST['website'])) die();
回答by Joseph K
An even simpler approach that works for me. Literally all spam that I receive(d), had a url in the message. So I filter on that, and have not received any spam messages since. I used to get about 10 a week.
一种更简单的方法对我有用。从字面上看,我收到的所有垃圾邮件(d),在邮件中都有一个 url。所以我对此进行了过滤,此后没有收到任何垃圾邮件。我以前每周大约有10个。
Add this under your line $error_message = ""; in your php-file:
在您的行下添加此 $error_message = ""; 在你的 php 文件中:
if(preg_match('/http|www/i',$comments)) {
$error_message .= "We do not allow a url in the comment.<br />";
}
The /i in the preg_match makes it case independent. The 'http' also filters for 'https'.
preg_match 中的 /i 使其与大小写无关。'http' 也过滤'https'。
回答by Alexandru Burca
Usually the bots submit a form very fast. So, based on that, another solution could be to add another hidden field that contain the number of seconds that passed from when the page was oppened. This can be done using JavaScript. Then check it in PHP. If the number of seconds is smaller than 5 seconds then it's spam (It's more likely that the real client needs more time to fit the form). You can adjust the number of seconds based on how many fields the form contain.
通常机器人提交表单的速度非常快。因此,基于此,另一种解决方案可能是添加另一个隐藏字段,其中包含从打开页面时经过的秒数。这可以使用 JavaScript 来完成。然后在PHP中检查它。如果秒数小于 5 秒,则它是垃圾邮件(更可能是真实客户端需要更多时间来适应表单)。您可以根据表单包含的字段数调整秒数。
回答by Rick Hellewell
Hidden fields, silly questions (what is 3+4?), etc, are not very effective at blocking spam on forms.
隐藏字段、愚蠢的问题(什么是 3+4?)等,在阻止表单上的垃圾邮件方面不是很有效。
I researched this several years ago, and came up with a solution I call "FormSpammerTrap". It uses JavaScript code to 'watch' for focus/onclick on required fields. Automated processes, unless highly customized for a specific site (which takes more time than spambot owners want to take), can't 'focus/onclick' a required field.
几年前我对此进行了研究,并提出了一个我称之为“FormSpammerTrap”的解决方案。它使用 JavaScript 代码来“观察”所需字段的焦点/点击。自动化流程,除非针对特定站点进行高度定制(这比垃圾邮件所有者想要花费的时间更长),否则无法“聚焦/点击”必填字段。
I have a free solution at my www.FormSpammerTrap.comsite. And there's a form there that spambots can try to spam...and they haven't, for more than 3 years. You are welcome to try it out...it's all open source, so you can see how it works. (And, if you use the form, I don't harvest your email. I reply once, then delete your email.)
我在www.FormSpammerTrap.com站点上有一个免费的解决方案。那里有一个表格,垃圾邮件机器人可以尝试发送垃圾邮件……但他们已经超过 3 年没有这样做了。欢迎您尝试一下……它都是开源的,因此您可以看到它是如何工作的。(而且,如果你使用表格,我不会收集你的电子邮件。我回复一次,然后删除你的电子邮件。)
My technique is much more effective in blocking spambots. They haven't been able to spambot the contact form on that site.
我的技术在阻止垃圾邮件机器人方面更有效。他们无法在该网站上发送垃圾邮件联系表。
回答by BenRoe
Create a form field and hide it for the users. In the php script check if this field is submitted, but empty. Now you know the request is from your form and a user.
创建一个表单域并为用户隐藏它。在 php 脚本中检查此字段是否已提交,但为空。现在您知道请求来自您的表单和用户。
Spam will fill the hidden field, or if they use your php script direct the spam protection field is not set.
垃圾邮件将填充隐藏字段,或者如果他们直接使用您的 php 脚本,则未设置垃圾邮件保护字段。
HTML
HTML
<input name="website" type="text" class="website"/>
CSS
CSS
form .website{ display:none; } /* hide because is spam protection */
PHP
PHP
# spam protection
if (isset($_POST["website"]) && $_POST["website"] == "") {
# your php code to mail here
} else {
http_response_code(400);
exit;
}
You can find more method's how to protect a php form spam here: https://zinoui.com/blog/protect-web-forms-from-spam
您可以在此处找到更多保护 php 表单垃圾邮件的方法:https: //zinoui.com/blog/protect-web-forms-from-spam
回答by rickdenhaan
If the spam you're getting does not have a comment, why not simply add a check for that? There's absolutely no reason for a real, human visitor to submit your contact form without a comment.
如果您收到的垃圾邮件没有评论,为什么不简单地添加一个检查?绝对没有理由让真正的人类访客在没有评论的情况下提交您的联系表格。
Since you don't want to add a captcha, the easiest solution in the short term would be to check that the comment is a minimum number of characters and contains at least a certain number of words.
由于您不想添加验证码,短期内最简单的解决方案是检查评论是否为最少字符数并且至少包含一定数量的单词。
For example:
例如:
$comments = trim($_POST['comments']); // trim() to strip off whitespace from beginning and end, like spaces and linebreaks
if (strlen($comments) < 20 || substr_count($comments, " ") < 3) {
died('Your comment is too short.');
}
This is a very simple check to see that the comment contains at least 20 characters and at least 3 spaces (4 words). Tweak as needed.
这是一个非常简单的检查,以查看评论是否包含至少 20 个字符和至少 3 个空格(4 个单词)。根据需要进行调整。
回答by docz
I have another method which I have used successfully on several web sites for over ten years, without so much as a single successful spam robot attack. I know from the server logs that the forms are spammed hundreds of times per day, but none of it has gotten through to me. This method doesn't need Captcha or any other purchased software. I will try not to give all the details here, but I'll say enough that most people can implement it. First, you will need a simple text-based graphic which shows an anti-spam "code' and, critically, the prompt for the form field with which it is used. Second, you will need an email script which will accept aliases (e.g. FormMail and many others). Create on your form a required field with the name of "recipient" (or whatever field name to which your email script expects to send the form input). Display your "code" graphic, with the embedded prompt next to it. Make sure that you set up your email script to accept whatever code you have used in the graphic as the alias for the real email recipient (you). When this is implemented, a human can easily read and enter the code you have chosen in your graphic (i.e. the email alias set up in the email script). A spam robot sees only a blank field. If the robot chooses to fill that field randomly, it will generate an error in the email script saying, in effect, that the recipient doesn't exist. You never see that error, nor do you ever get any spam. I have tried most of the other approaches described in other posts here, but none has been 100% effective as this one has been. Of course, a human being can defeat this, but if he does you simply change the graphic and the email alias in your script setup. Then, he must start over with a manual submission.
我有另一种方法,我在几个网站上成功使用了十多年,没有一次成功的垃圾邮件机器人攻击。我从服务器日志中知道,这些表单每天被垃圾邮件发送数百次,但我没有收到任何邮件。此方法不需要验证码或任何其他购买的软件。我尽量不在这里提供所有细节,但我会说得足够多,大多数人都可以实现它。首先,您需要一个简单的基于文本的图形,该图形显示反垃圾邮件“代码”,关键是使用它的表单字段的提示。其次,您需要一个接受别名的电子邮件脚本(例如FormMail 和其他许多)。在您的表单上创建一个名为“收件人”的必填字段 (或您的电子邮件脚本希望将表单输入发送到的任何字段名称)。显示您的“代码”图形,旁边有嵌入的提示。确保您将电子邮件脚本设置为接受您在图形中使用的任何代码作为真实电子邮件收件人(您)的别名。实施后,人们可以轻松阅读并输入您在图形中选择的代码(即在电子邮件脚本中设置的电子邮件别名)。垃圾邮件机器人只能看到一个空白字段。如果机器人选择随机填充该字段,它将在电子邮件脚本中生成一个错误,表明实际上收件人不存在。您永远不会看到该错误,也不会收到任何垃圾邮件。我已经尝试了此处其他帖子中描述的大多数其他方法,但没有一种方法像这个方法一样 100% 有效。当然,一个人可以打败它,但如果他做到了,您只需更改脚本设置中的图形和电子邮件别名。然后,他必须重新开始手动提交。