Honeypot - простая эффективная защита форм на сайте от спама
Пост продемонстрирует простую технику, которая поможет вам блокировать спамеров и ботов, атакующих формы вашего веб-сайта
Хотелось бы предупредить заранее, что не стоит рассматривать эту защиту как панацею от всех атак, это скорее дополнительный уровень защиты от спама, а не основной функционал. Возможно для вашего ресурса понадобятся более продвинутые системы, такими как reCaptcha и т.д. Но из-за простоты этого метода я рекомендую вам не игнорировать его применение в своих формах.
Итак, представьте, что у вас есть обычная структура формы, следующего вида:
<form id="form" action="/send">
<label for="name">* Ваше имя:</label>
<input type="text" id="name" name="name" placeholder="Введите имя" required maxlength="100">
<label for="email">* Ваш E-mail:</label>
<input type="email" id="email" name="email" placeholder="Введите e-mail" required>
<input type="submit" value="Отправить" />
</form>
Т.к. большинство ботов - тупые, у них стоит задача заполнить все поля формы, ведь на форме могут быть различные чекбоксы типа "Соглашаюсь с ..", на этом и строится вся логика "Приманки".
Поэтому если мы немного дополним форму чекбоксом с именем, ну например fax_only, и скроем его с глаз с помощью стиля display:none:
<form id="form" action="/send">
<label for="name">* Ваше имя:</label>
<input type="text" id="name" name="name" placeholder="Введите имя" required maxlength="100">
<label for="email">* Ваш E-mail:</label>
<input type="email" id="email" name="email" placeholder="Введите e-mail" required>
<input type="checkbox" name="fax_only" id="fax_only" value="1" style="display:none;" autocomplete="off" />
<input type="submit" value="Отправить" />
</form>
Как вариант, еще можно скрыть элемент без использования diplay:none, т.к. некоторые боты могут это "учуять":
.hidden {
opacity: 0;
position: absolute;
top: 0;
left: 0;
height: 0;
width: 0;
z-index: -1;
}
Но в большинстве случаев даже display none вполне себе рабочий вариант, если же боты все же будут пробивать защиту можно озадачиться усовершенствованием стилей.
Теперь в форме есть 2 вида данных: реальные поля с нашими входными данными (и возможно защищенными хешами) и наш приманка (лучше всего использовать более менее реальные имена, и не использовать "honeypot" и пр. "приманочные" имена).
На бэкэнде достаточно сделать проверку не было ли заполнено какое-либо из полей «honeypot». Если да, поздравляю, вы поймали спам. Большинство ботов заполнит все поля, не различая их. Если вы предпочитаете выполнить эту проверку на клиенте, в случае формы ajax, то это позволит избежать использования ресурсов сервера для вычисления бесполезных данных (но все равно сохраните проверку и на бэкенде). Когда вы поймаете спам, просто не отправляйте данные и делайте с ними все, что хотите. Пример для Laravel:
public function send(Request $request)
{
if ($request->fax_only){
die();
}
//вроде как не спам
}
Ну или просто проверка $_REQUEST в PHP:
if (isset($_REQUEST["fax_only"]) && !empty($_REQUEST["fax_only"])) {
die();
}
Есть еще более продвинутые варианты реализации "приманки" с помощью JavaScript, но как уже писал выше обычно достаточно и простого варианта, а совершенствовать ее можно по мере того, как боты смогут и будут обходить вашу защиту.
Виталя21.07.2023
Для чекбокса достаточно проверки isset($_REQUEST["fax_only"]), так как если он не выбран, то нет такого элемента в массиве $_REQUEST.