Защита форм от спама без капчи — 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+ ссылок — это спам.

Очерёдность защиты

  1. CSRF-токен — отбрасываем 30% ботов.
  2. Honeypot — отбрасываем ещё 60% (суммарно ~70%).
  3. Временной токен — ещё 10% (суммарно ~80%).
  4. Rate limit — ещё 10% (суммарно ~90%).
  5. Проверка содержимого — ещё 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. Капча подключается только если эта связка не справляется или для критических сценариев (регистрация, восстановление пароля, публикация).

Узнайте подробнее о наших компетенциях
Разработка, ИИ, автоматизация — что мы делаем и как.