Лид-форму защищают несколькими дешёвыми слоями. Скрытое поле-ловушка, минимальное время заполнения, строгая проверка на сервере, лимиты частоты, поиск дублей и, для дорогих лидов, подтверждение телефона или почты. Капча идёт сверху и нужна, когда дешёвые слои пропускают слишком много.
Порядок важен, потому что у каждого слоя есть цена. Лишнее поле или головоломка снижает конверсию живых людей, поэтому сначала включают проверки, которых человек не видит, и трение добавляют там, где это оправдано цифрами.
Начните с невидимых проверок (honeypot, время заполнения, валидация на сервере, лимит частоты), добавьте поиск дублей и подтверждение для ценных лидов, капчу оставьте напоследок. Отдельно уменьшайте число ботов-кликов до страницы. TDS.SO делает вторую часть: фильтрует клики на ссылке, перед лендингом. Саму форму он не защищает.
Две разные проблемы, которые выглядят одинаково
Мусорные заявки приходят из двух мест. Одни отправляют скрипты, которые находят форму и шлют данные напрямую, не загружая страницу как браузер. Другие приходят вместе с автоматическими посетителями: те попадают на лендинг по вашей рекламной ссылке, загружают его и иногда заполняют форму по команде скрипта.
Первую группу закрывают на самой форме и на её эндпоинте. Вторую дешевле остановить раньше, на клике. Если лечить обе группы одной капчей, вы платите за каждый бот-клик, раздражаете живых и всё равно пропускаете скрипты, которые бьют в эндпоинт без браузера. Как узнавать вторую группу в логе кликов, описано в статье признаки бот-трафика.
Слой 1: поле-ловушка (honeypot)
Honeypot это лишний input, которого живой человек не видит. Его прячут через CSS (не через type="hidden", такие поля простые боты пропускают), дают привлекательное имя вроде website или company и отклоняют любую отправку, где поле заполнено.
<div style="position:absolute;left:-9999px" aria-hidden="true">
<label>Оставьте пустым
<input type="text" name="website" tabindex="-1" autocomplete="off">
</label>
</div>
Поставьте autocomplete="off" и tabindex="-1", иначе автозаполнение браузера или навигация с клавиатуры заполнят поле, и вы отклоните настоящих людей. Проверяйте поле на сервере. Ловушка ловит примитивные скрипты и больше ничего, поэтому считайте её бесплатным первым фильтром.
Слой 2: время заполнения
Человеку нужно несколько секунд, чтобы прочитать форму и ввести данные. Скрипт отправляет за миллисекунды. Когда отдаёте форму, положите в подписанный токен время выдачи и сравните его со временем прихода заявки.
- Отклоняйте отправки быстрее выбранного порога, например 3 секунд для формы из нескольких полей.
- Отклоняйте слишком старые токены (скажем, старше суток): повторное использование токенов частый приём.
- Подписывайте токен на сервере, чтобы его нельзя было подделать правкой страницы.
Порог ставьте с запасом. Автозаполнение может заполнить форму секунды за полторы, и слишком жёсткий лимит отсечёт живых людей. Неделю просто логируйте отказы, прежде чем что-то блокировать.
Слой 3: проверка на сервере
Всё, что проверяется в браузере, можно обойти прямой отправкой на эндпоинт. Важные правила должны жить на сервере.
- Типы и длины. Имя в 4000 символов или телефон с буквами на человека не похожи.
- Формат. Приводите телефоны к одному виду и проверяйте, что код страны совпадает с рынком, на который вы льёте.
- Допустимые значения. Списки и радиокнопки должны принимать только те значения, которые вы отрисовали.
- Содержимое. Отклоняйте ссылки в полях, где им делать нечего, и очевидные заглушки вроде
testилиasdf. - Происхождение. Проверяйте заголовки
OriginилиRefererи CSRF-токен. Настойчивый скрипт их подделает, но небрежные остановятся.
Слой 4: лимиты частоты
Ограничьте число отправок с одного IP, из одной сессии и с одного устройства за окно времени. Для обычной лид-формы разумное начало около 3 отправок с IP в час, дальше подстройте под свои логи.
Две оговорки. Мобильные операторы и офисы отдают один IP многим людям, поэтому перед блокировкой сочетайте IP с cookie или сессией и предпочитайте мягкий ответ (задержку или капчу) жёсткому бану. И отвечайте одинаково, приняли вы заявку или отклонили, чтобы скрипт не понял, какое правило сработало.
Капча и её цена
Капча работает, и стоит денег. Видимая головоломка добавляет шаг и может снизить долю завершивших форму. Невидимые и оценочные версии прячут эту цену от большинства людей, но зависят от стороннего скрипта, могут ошибаться на пользователях с VPN или редкими браузерами и поднимают вопросы приватности, которые, возможно, придётся описать в политике. Для большинства типов капч есть сервисы решения, так что настойчивого атакующего она замедляет, а не останавливает.
| Способ | Цена для живых | Останавливает | На что смотреть |
|---|---|---|---|
| Honeypot | Нет | Примитивные скрипты | Автозаполнение скрытого поля |
| Время заполнения | Нет | Мгновенные отправки | Слишком высокий порог |
| Лимит частоты | Низкая | Потоки с одного источника | Общие IP |
| Невидимая капча | Низкая | Многих типовых ботов | Сторонний скрипт, ложные срабатывания |
| Видимая капча | Средняя или высокая | Многих ботов | Падение доли завершивших |
| Подтверждение телефона или почты | Высокая | Фейковые контакты | Отвал людей, стоимость SMS |
Практическое правило: показывайте капчу только тем отправкам, которые уже выглядят подозрительно (не прошли проверку времени, всплеск с одного IP), остальных не трогайте.
Подтверждение контакта и дубли
Правдоподобные данные всё равно могут быть фейком. Для лидов, которые дорого обрабатывать, подтверждайте контакт до того, как заявка попадёт в работу. Отправьте одноразовый код на телефон или ссылку на почту и засчитывайте лид только после использования. Часть живых людей на этом шаге отвалится, поэтому применяйте его там, где фейковый лид обходится дороже потерянного.
Поиск дублей дешевле и ловит много. Хэшируйте нормализованные телефон и почту и ищите повторы в окне времени, отмечайте несколько заявок с одним IP и user agent за минуты. Заранее решите, что для вас дубль: повторная отправка одним человеком и один номер под пятью разными именами требуют разной реакции.
Фильтрация бот-кликов до страницы
Всё перечисленное выше срабатывает, когда посетитель уже загрузил ваш лендинг, то есть клик уже оплачен. Если часть трафика автоматическая, её можно уменьшить раньше, на ссылке.
TDS.SO делает это на рекламной ссылке. Вы выбираете уровень фильтра (Выкл, Стандартный, Высокий, JavaScript (проверка браузера) или Свой) и отмечаете сигналы: неизвестная платформа, неизвестный браузер, пустая страна, пустой город, IPv6, дата-центры, VPN, пустой реферер. Клики, не прошедшие проверку, уходят на страницу, которую вы задали, и остаются в логе кликов с причиной (vpn, datacenter, suspicious_headers и другие), так что можно проверить, что именно отфильтровано. Подробности на странице защиты от ботов.
Границы нужно назвать прямо. Фильтр работает на ссылке, до лендинга. Он не видит вашу форму, не проверяет поля и не остановит скрипт, который шлёт данные прямо на эндпоинт формы. Эти слои остаются вашей задачей. Считайте два подхода дополняющими друг друга: один сокращает мусорный трафик, другой мусорные заявки. Строгий уровень может зацепить и живых людей на VPN, поэтому начинайте с мягкого и читайте лог.
Что логировать и как настраивать пороги
Любая защита без журнала работает вслепую. Для каждой заявки сохраняйте время выдачи формы и время отправки, IP, user agent, значение honeypot, результат каждой проверки и причину отказа. Первую неделю ничего не блокируйте: помечайте заявки как подозрительные и сравнивайте с тем, что потом реально оказалось мусором. Так вы увидите, какой слой ловит больше всего и какой задевает живых людей.
Отдельно заведите папку или статус для отклонённых заявок и раз в неделю просматривайте её глазами. Пара ложных срабатываний в такой папке лучше, чем незаметно потерянные оплаченные лиды. Пороги (секунды, число отправок в час, правила для дублей) меняйте по одному и после каждого изменения смотрите на долю отклонённых и на количество жалоб от живых клиентов.
Вопросы и ответы
Хватит ли одного honeypot?
Для небольшой формы с малым трафиком на время, возможно, хватит. Скрипты, которые рендерят страницу или читают имена полей, его пройдут. Сочетайте с проверкой времени и серверной валидацией.
Капча снижает конверсию?
Видимая головоломка добавляет шаг, поэтому может. Размер эффекта зависит от аудитории и формы, измерьте его сплит-тестом. Показ только подозрительным отправкам ограничивает цену.
Как понять, откуда мусор: из бот-кликов или из прямых отправок?
Сравните время заявок с логом кликов. Если у мусорных заявок есть соответствующие клики из дата-центров или с VPN, источник трафик. Если заявки приходят без клика вообще, что-то шлёт данные напрямую на ваш эндпоинт.
Стоит ли блокировать по IP?
Используйте IP как один из сигналов, не единственный. Общие и мобильные IP значат, что блокировка заденет живых людей, а атакующие меняют адреса. Компромиссы разобраны в статье JS-fingerprint или блок по IP.
Фильтр трафика защищает форму?
Нет. Фильтр кликов работает до лендинга и уменьшает число автоматических посетителей. Форме по-прежнему нужна собственная защита.
Если бот-клики входят в вашу проблему с мусорными заявками, настройте фильтрацию на ссылке через защиту от ботов TDS.SO, а проверки формы из этой статьи оставьте на своей стороне.
Гайды и разборы о маршрутизации, фильтрации ботов и трекинге от команды TDS.SO.
Все статьи автора