Защита форм от спама без капчи — honeypot, rate limit, токены
Каждая капча на форме режет 5-15% конверсии. На большинстве сайтов её можно убрать совсем — связка honeypot + rate limit + временной токен ловит 95% автоматического спама невидимо для пользователя. Разбираем 5 техник и порядок их подключения.
Капча — самое раздражающее на форме. По данным WPForms 2025, каждое внедрение reCAPTCHA снижает конверсию формы на 6-15%. Это огромная цена за защиту, которая в большинстве случаев избыточна.
Связка из 5 техник без капчи ловит 95% спама и не показывает пользователю ничего. Подключается за 1-2 часа работы.
1. Honeypot — основа
Невидимое поле в форме. Бот, обходящий форму, заполняет всё подряд, включая это поле. Человек его не видит и не заполняет.
<form action="/lead" method="post">
<input name="name" placeholder="Имя">
<input name="phone" placeholder="Телефон">
<!-- honeypot -->
<input type="text" name="website" tabindex="-1"
autocomplete="off"
style="position:absolute;left:-9999px;
opacity:0;height:0;width:0;">
<label for="website" style="display:none"
aria-hidden="true">Не заполняйте, если вы человек</label>
<button type="submit">Отправить</button>
</form>
На сервере:
if (!empty($_POST['website'])) {
http_response_code(200);
exit; // тихо отбрасываем, не сигнализируем боту
}
Тихий ответ 200 без обработки — бот думает, что заявка принята, не пробует ещё раз.
2. Имя поля имеет значение
Боты обучены не трогать поля с очевидными названиями captcha, spam_check, hp_field. Используйте безобидные имена:
website— самый частый, заполняют 90% ботов.url,blog,company_url.fax— анахронизм, но боты заполняют.
Меняйте поле раз в полгода — продвинутые боты адаптируются.
3. Временной токен
Боты заполняют форму за миллисекунды. Человек тратит минимум 3-5 секунд (даже на коротких формах).
При рендере формы сервер записывает временную метку в скрытое поле или сессию:
// при рендере
$_SESSION['form_ts'] = time();
// при обработке
if (time() - $_SESSION['form_ts'] < 3) {
http_response_code(200);
exit; // подозрительно быстро
}
if (time() - $_SESSION['form_ts'] > 3600) {
// форма открыта больше часа — устарела
return redirect_with_error('Перезагрузите форму');
}
Боты, которые ждут несколько секунд перед отправкой, есть, но их единицы.
4. Rate limit на сервере
Один IP не может отправить форму чаще одного раза в 30-60 секунд. Ловит массовые рассылки.
$ip = $_SERVER['REMOTE_ADDR'];
$key = "form_lock_" . hash('sha256', $ip);
// в Redis или apcu
if (apcu_exists($key)) {
http_response_code(429);
exit('Слишком много запросов. Попробуйте через минуту.');
}
apcu_store($key, 1, 30); // 30 секунд
Для сайта с большим трафиком — поднимайте лимит до 2-3 в минуту. Иначе несколько сотрудников из одного офиса попадут под блок.
5. CSRF-токен с привязкой к сессии
Не защита от спама напрямую, но усложняет ботам жизнь. Бот должен сначала загрузить страницу с формой, парсить токен, прислать вместе с данными.
// при рендере
$_SESSION['csrf'] = bin2hex(random_bytes(16));
<input type="hidden" name="csrf" value="<?= $_SESSION['csrf'] ?>">
// при обработке
if (empty($_POST['csrf']) || $_POST['csrf'] !== $_SESSION['csrf']) {
http_response_code(403);
exit;
}
Срезает дешёвые HTTP-боты, которые просто шлют POST на эндпоинт без захода на форму.
Дополнительные сигналы
- User-Agent: пустой или явно «curl/7.x», «python-requests» — режим. Реальные браузеры имеют осмысленный UA.
- Referer: если форма отправлена с пустым Referer, скорее всего бот. Не строгая проверка, но сигнал.
- JavaScript-нонс: при загрузке страницы JS считает простое выражение и пишет в hidden-поле. Боты без браузера не выполнят.
- Содержимое: проверка простой регулярки. Если в поле «Имя» стоит URL или 5+ ссылок — это спам.
Очерёдность защиты
- CSRF-токен — отбрасываем 30% ботов.
- Honeypot — отбрасываем ещё 60% (суммарно ~70%).
- Временной токен — ещё 10% (суммарно ~80%).
- Rate limit — ещё 10% (суммарно ~90%).
- Проверка содержимого — ещё 5% (суммарно ~95%).
Оставшиеся 5% — продвинутые ферм-боты. Если они становятся проблемой — подключайте SmartCaptcha.
Что НЕ работает
- Проверка User-Agent как единственная защита. Подделывается за минуту.
- Скрытое поле, помеченное
display: none. Боты читают CSS, пропускают такие поля. Используйте off-screen позиционирование. - Капча текстом «введите слово «человек»». Все боты это читают и заполняют. Бесполезно.
- Блокировка по гео-IP. Тяжело поддерживать, режет реальных юзеров через VPN.
Что делать после внедрения
- Логируйте все отброшенные попытки с указанием, какая проверка сработала. Через месяц видно, какая защита работает, а какая мёртвая.
- Мониторьте «качество лидов» в первые недели — не блокирует ли защита реальных пользователей.
- Раз в полгода меняйте имя honeypot-поля.
- Не показывайте сообщения «вы не прошли проверку» — это подсказка боту, что защита есть.
Когда капча нужна обязательно
- Формы регистрации с открытием аккаунта.
- Форма восстановления пароля (защита от перебора).
- Публикация контента (комментарии, отзывы) — защита от спам-ссылок.
- Если лиды стоят >5 тыс ₽ и боты пытаются «вброс» — оправдан даже невидимый SmartCaptcha.
Вывод
5 техник без капчи (CSRF + honeypot + временной токен + rate limit + проверка содержимого) ловят 95% спама невидимо для пользователя. Подключаются за 1-2 часа. Дают +5-15% к конверсии формы по сравнению с reCAPTCHA. Капча подключается только если эта связка не справляется или для критических сценариев (регистрация, восстановление пароля, публикация).