Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent php web contact form spam

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 = "[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();
?>
like image 937
user7858610 Avatar asked Apr 12 '17 20:04

user7858610


People also ask

How do I secure a contact form?

Block copy and paste in your forms. Another way to prevent contact form spam is to disable the right-click functionality. Your contact forms will only be secured from human spammers who copy and paste their details into your forms.


3 Answers

A simple trick is to create a honeypot field:

html

<!-- within your existing form add this field -->
<input type="text" id="website" name="website"/>

css

/*in your css hide the field so real users cant fill it in*/
form #website{ display:none; }

php

//in your php ignore any submissions that inlcude this field
if(!empty($_POST['website'])) die();
like image 76
Steve Avatar answered Oct 13 '22 17:10

Steve


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

like image 45
Joseph K Avatar answered Oct 13 '22 17:10

Joseph K


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.

like image 4
Alexandru Burca Avatar answered Oct 13 '22 16:10

Alexandru Burca