Предотвращение спама в веб-форме php

Я - любительский веб-дизайнер, я искал на stackoverflow.com и других веб-сайтах и нашел много исправлений для этой проблемы, которые у меня есть, но никто из них не работал (возможно, потому, что я их неправильно реализую). Я надеюсь, что кто-то с большим количеством знаний может помочь мне с простым исправлением или показать мне, как реализовать одно из исправлений, которые я нашел.

Проблема: у меня очень простая контактная форма php на моем бизнес-сайте. Он отлично справился годами, но на прошлой неделе был взломан. Теперь я получаю сотни сообщений о форме контакта в день без комментариев, у них есть (видимо, действительные) адреса электронной почты и строка символов в поле имени (например, "58ee8b52eef46").

Я пробовал несколько методов для предотвращения этого спама, и они либо ломают мою php-форму, либо не предотвращают спам. Если возможно, я хотел бы получить решение, для которого НЕ требуется Captcha-искаженный текстовый тест, и НЕ требует заполнения всех полей формы.

Вот мой полный 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();
?>

Ответ 1

Простым трюком является создание поля honeypot:

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();

Ответ 2

Скрытые поля, глупые вопросы (3 + 4?) И т.д. Не очень эффективны при блокировании спама на формах.

Я исследовал это несколько лет назад и придумал решение, которое я называю "FormSpammerTrap". Он использует код JavaScript для "просмотра" для фокуса /onclick в обязательных полях. Автоматизированные процессы, если они не настроены специально для определенного сайта (который занимает больше времени, чем владельцы spambot хотят взять), не могут "сфокусировать/отключить" нужное поле.

У меня есть бесплатное решение на моем сайте www.FormSpammerTrap.com. И там есть форма, где спам-боты могут пытаться спамить... и их нет, более 3 лет. Вы можете попробовать... все это с открытым исходным кодом, чтобы вы могли видеть, как это работает. (И, если вы используете форму, я не собираю вашу электронную почту. Я отвечаю один раз, а затем удаляю вашу электронную почту.)

Моя техника намного эффективнее блокирует спам-боты. Они не смогли создать контактную форму на этом сайте.

Ответ 3

Создайте поле формы и скройте его для пользователей. В скрипте php проверьте, отправлено ли это поле, но пустое. Теперь вы знаете, что запрос от вашей формы и пользователя.

Спам заполнит скрытое поле, или если он использует ваш скрипт php напрямую, поле защиты от нежелательной почты не будет установлено.

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;
}

Вы можете найти еще один способ защиты спама в php-форме: https://zinoui.com/blog/protect-web-forms-from-spam

Ответ 4

Если спам, который вы получаете, не имеет комментария, почему бы просто не добавить чек для этого? Нет абсолютно никаких оснований для того, чтобы настоящий, посетитель посетил вашу контактную форму без комментариев.

Поскольку вы не хотите добавлять капчу, самым легким решением в краткосрочной перспективе будет проверка того, что комментарий является минимальным количеством символов и содержит по крайней мере определенное количество слов.

Например:

$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.');
}

Это очень простая проверка, чтобы увидеть, что комментарий содержит не менее 20 символов и не менее 3 пробелов (4 слова). При необходимости отрегулируйте.

Ответ 5

Еще более простой подход, который работает для меня. Буквально весь спам, который я получаю (d), имел URL в сообщении. Поэтому я отфильтровываю это и с тех пор не получал никаких спам-сообщений. Раньше я получал около 10 в неделю.

Добавьте это под вашей строкой $ error_message = ""; в вашем php файле:

if(preg_match('/http|www/i',$comments)) {
    $error_message .= "We do not allow a url in the comment.<br />";
  }

/i в preg_match делает его независимым от регистра. "Http" также фильтрует для "https".