Prevent php web contact form spam

2020-05-18 16:49发布

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.

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").

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.

Here is my full PHP code:

<?php
if(isset($_POST['email'])) {
  $email_to = "myemail@example.com";
  $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();
?>

7条回答
迷人小祖宗
2楼-- · 2020-05-18 17:31

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.

Add this under your line   $error_message = "";   in your php-file:

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'.

查看更多
The star\"
3楼-- · 2020-05-18 17:31

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.

查看更多
Emotional °昔
4楼-- · 2020-05-18 17:31

Hidden fields, silly questions (what is 3+4?), etc, are not very effective at blocking spam on forms.

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.

I have a free solution at my www.FormSpammerTrap.com site. 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.)

My technique is much more effective in blocking spambots. They haven't been able to spambot the contact form on that site.

查看更多
劳资没心,怎么记你
5楼-- · 2020-05-18 17:38

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.

查看更多
何必那么认真
6楼-- · 2020-05-18 17:41

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.

Spam will fill the hidden field, or if they use your php script direct the spam protection field is not set.

HTML

<input name="website" type="text" class="website"/>

CSS

form .website{ display:none; } /* hide because is spam protection */

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

查看更多
7楼-- · 2020-05-18 17:49

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.

查看更多
登录 后发表回答