В почте появляются десятки одинаковых заявок, а в CRM — пустые карточки и случайные ссылки. Первая реакция — поставить CAPTCHA на все формы и заблокировать подозрительные адреса. Но шум может возникать по разным причинам: автоматическая рассылка, двойной клик клиента, повтор после долгого ответа сайта или ошибка передачи в CRM. Если смешать их в одну категорию, можно остановить ботов и заодно потерять настоящие обращения.
Сначала определите, что именно происходит
Под спамом здесь понимаем нежелательные обращения: рекламные рассылки, бессмысленные сообщения и массовые автоматические отправки. Но две одинаковые записи ещё не доказывают атаку. Клиент мог нажать кнопку повторно, обновить страницу после таймаута или отправить ту же форму на телефоне и компьютере. Интеграция тоже может создать дубль: сайт записал обращение, не дождался ответа CRM и повторил передачу.
Проверьте путь заявки по этапам: запрос дошёл до сайта, прошёл проверку, сохранился, ушёл в почту или CRM. Сравните время, контактные данные, статус ответа и идентификатор записи. Так можно увидеть, где возникли дубли и что именно следует ограничивать. В статье о поиске потерянных заявок разобраны серверная запись и повтор передачи в CRM после таймаута. Если подтверждения нет, не называйте запись спамом только по необычному адресу или тексту.
Одинаковые обращения могут появиться на разных этапах. Сначала найдите источник повтора, затем выбирайте защиту.
В статье о регулярной техподдержке сайта прогон форм включён в плановую проверку. Такой тест полезен после обновлений, изменений формы и подключения новых обработчиков.
Базовая защита должна работать на сервере
Проверки в браузере помогают человеку заполнить форму без ошибок: подсвечивают пустое обязательное поле или неверный формат телефона. Но их можно отключить или обойти, отправив запрос напрямую. Сервер должен самостоятельно проверить обязательные поля, допустимый формат и длину значений, тип операции и контекст формы. Клиентская проверка улучшает удобство, серверная принимает решение.
Валидация не означает, что нужно угадывать «правильный» текст. Задайте понятные ограничения: обязательные поля, предельную длину комментария, допустимый размер и тип вложения, если файлы нужны. Ограничивайте тело запроса и число файлов до запуска тяжёлой обработки. Сначала отклоните заведомо неподходящий запрос, потом создавайте миниатюры, отправляйте письмо или вызывайте внешние API. Для вложений проверяйте не только имя файла, но и фактический формат средствами сервера.
CSRF-защита нужна для своей задачи — снижать риск нежелательных действий от имени пользователя в его браузере. Она не является фильтром ботов: бот может открыть публичную форму, получить собственную сессию и корректный токен. Наличие токена не доказывает, что форму заполняет человек. Поэтому CSRF-токен не заменяет серверную валидацию и антиспам-меры. OWASP также рекомендует проверять данные на сервере, даже если интерфейс уже проверил их до отправки.
Лимитируйте по нескольким признакам
Одного ограничения «не больше одной заявки с IP» обычно недостаточно. В офисе, гостинице, мобильной сети или за общим прокси у множества реальных людей может быть один внешний адрес. Жёсткий IP-лимит способен закрыть форму всему офису из-за одного активного пользователя.
Используйте комбинацию сигналов: частота запросов к конкретной форме, число неуспешных проверок, повторяемость содержимого, возраст сессии или результат антибот-проверки. Учитывайте короткие всплески и общий объём за более длинный интервал. Один неоднозначный признак может стать поводом для дополнительной проверки, а сочетание нескольких — для временного ограничения. Конкретные пороги подбирают по журналам сайта, а не переносят универсальные значения без проверки.
Не считайте очередь защитой от спама. Очередь помогает обработать нагрузку и повторить передачу при временном сбое, но сама по себе принимает столько задач, сколько ей подали. Ограничение должно срабатывать до постановки дорогой работы в очередь. А повтор передачи в интеграцию следует отличать от новой пользовательской отправки: связывайте его с уже сохранённым обращением, чтобы не создавать дубль.
Ограничения на размер и частоту стоят перед дорогой обработкой. Очередь помогает доставке, но не заменяет эти проверки.
Honeypot, CAPTCHA и доступность
Скрытое поле-ловушка, или honeypot, может отмечать автоматическую отправку, если в него попало значение. Но при неосторожной разметке его могут заполнить автозаполнение браузера или вспомогательная технология. Нельзя рассчитывать на этот приём как на единственный фильтр. Не создавайте ловушку, которая попадает в обычный порядок клавиатурной навигации или озвучивается скринридером как обязательное поле. Проверьте форму с клавиатурой и автозаполнением, а подозрительное срабатывание оценивайте вместе с другими сигналами.
CAPTCHA добавляет шаг, поэтому включайте её там, где риск подтверждён: например, после серии подозрительных отправок или перед повтором, который не проходит тихие проверки. Если поставщик позволяет, применяйте проверку по риску и продумайте альтернативный путь для посетителя, который не может пройти испытание. Объясните, что произошло, не стирайте уже введённый текст и дайте повторить отправку или связаться другим способом. В проекте обзора рабочей группы W3C о доступности CAPTCHA разобраны ограничения таких проверок: один аудиовариант тоже подходит не всем.
Для Cloudflare Turnstile токен нужно проверять серверным запросом к Siteverify; наличие виджета в браузере не означает, что заявка прошла проверку. Секретный ключ хранится на сервере, а не в коде страницы. Срок жизни токена и возможность его повторного использования зависят от провайдера и его правил. В документации Turnstile отдельно указаны серверная валидация и параметры доступности, включая управление клавиатурой; конкретную конфигурацию всё равно следует проверить на своей форме. Если внешний сервис проверки временно недоступен, заранее определите запасной сценарий: ограниченный приём на ручную проверку либо альтернативный способ связи. Не считайте ошибку сервиса успешной проверкой. Молчаливый отказ для всех посетителей превращает защиту в потерю заявок.
Ошибка не должна превращать отправку в лотерею
После нажатия кнопки клиенту нужен ясный статус: заявка принята, данные требуют исправления или сервис проверки временно недоступен. При ошибке валидации сохраните введённые значения и покажите, какое поле поправить. После таймаута сайт должен по возможности выяснить статус предыдущей попытки; посетителю не нужно самостоятельно искать запись в CRM. Для защиты от двойной отправки сервер должен распознавать повтор одной операции по устойчивому идентификатору и возвращать результат уже сохранённой заявки. Это поведение нужно реализовать и проверить, в том числе для одновременных запросов; одного поля с ID недостаточно.
Если токен CAPTCHA истёк, обновите проверку, сохранив текст формы. Если он уже использован, сначала выясните статус исходной попытки: заявка могла быть принята. Точные правила зависят от поставщика. Если проверочный сервис недоступен, покажите понятное сообщение и предложите согласованный запасной канал — телефон, почту или повтор позже. Если предусмотрен ограниченный приём без результата CAPTCHA, сохраните обращение с отдельным статусом для ручной проверки. Подтверждайте приём только после сохранения. Если такой сценарий не реализован, прямо сообщите, что заявка не принята, и покажите запасной канал.
Повтор должен сохранять введённое и не создавать вторую запись. Для каждого исхода нужен понятный следующий шаг.
Внедряйте постепенно и смотрите на последствия
Перед изменением зафиксируйте текущую картину: сколько обращений приходит, сколько выглядит мусором, сколько клиентов сообщают о проблемах. После включения каждого правила сравнивайте не только объём спама, но и успешные отправки, ошибки формы, жалобы и случаи ложной блокировки. Не храните лишние персональные данные в технических логах; для диагностики обычно достаточно времени, результата проверки, идентификатора формы и корреляционного ID заявки.
Практический порядок внедрения:
- Проверьте путь тестового обращения до сохранения и интеграций; найдите, где появляются повторы.
- Добавьте серверную проверку полей и ранние пределы для размера запроса, длины текста и файлов.
- Включите умеренные лимиты по нескольким признакам и отслеживайте влияние на посетителей общих сетей.
- Добавьте honeypot только после проверки автозаполнения и доступности; применяйте CAPTCHA по риску и проверяйте токены на сервере.
- Отработайте сценарии успеха, таймаута, ошибки проверки и недоступности антибот-сервиса. Убедитесь, что повтор не стирает текст и не дублирует заявку.
- Пересматривайте правила по метрикам: доля мусорных обращений, успешные отправки, ошибки, жалобы и ложные блокировки.
Ни одна отдельная мера не гарантирует отсутствие спама. Цель — снизить автоматический мусор, не мешая реальному посетителю оставить обращение и сохраняя понятный путь восстановления при сбое.
Источники
OWASP: Input Validation Cheat Sheet; OWASP: ограничения частоты запросов и ресурсов; Cloudflare Turnstile: Server-side validation; Cloudflare Turnstile: параметры виджета и доступность.
Нужно проверить защиту форм на сайте?
SolverWeb может проверить путь отправки, серверную валидацию, лимиты, сохранение заявок и поведение формы при сбоях CAPTCHA или интеграции. Обсудите задачу и подходящий объём работ на странице контактов SolverWeb.








Обсуждение
Поделитесь мнением — первый комментарий задаст тон.