Перейти до змісту
Меню

Безпека

Захист форми на сайті: спам, боти, витоки

Захист форми на сайті на практиці: як зупинити спам і ботів, заблокувати ін’єкції та зловживання і не допустити витоку персональних даних заявок.

Опубліковано
Оновлено
хв читання
6 хв читання
Автор:
Редакція Kyvrel

Захист форми на сайті - це три завдання: не пустити ботів, не дати використати форму на шкоду і вберегти персональні дані, які вам надсилають. Жоден окремий трюк не закриває всі три. Honeypot, серверна валідація, обмеження частоти запитів і уважність до того, куди потрапляють заявки, знімають більшість проблем, а справжні клієнти нічого не помічають.

Форма зворотного зв’язку часто єдине місце маркетингового сайту, яке приймає дані від незнайомців. Тому це найвразливіша поверхня сайту і та, що найшвидше засмічує пошту. У статті розбираємо шари захисту, які ми закладаємо в кожну форму, з прикладами, які можна передати розробнику.

Що насправді охоплює захист форми на сайті

Коли команда каже «на форму йде спам», зазвичай мається на увазі одна з кількох різних проблем. Їх варто назвати, бо кожна потребує свого рішення.

  • Спам і боти. Автоматичні скрипти надсилають рекламу, посилання і сміття, часом тисячі разів на день.
  • Зловживання формою. Зловмисники намагаються розсилати через неї листи іншим людям, завалити вашу пошту або промацати сервер.
  • Ін’єкції. Введення, сконструйоване так, щоб вийти за межі поля: у заголовки листа, в адмінку чи в запит до бази.
  • Витоки даних. Заявки опиняються там, де не повинні: у незахищеній скриньці, у лог-файлі, у сторонньому сервісі без договору.

Безпечна форма справляється з усіма чотирма. Більшість проблемних форм, які ми перевіряємо, закривають лише першу, і то капчею, що дратує живих людей.

Чому на форми зворотного зв’язку йде стільки спаму?

Форми легко знайти і дешево атакувати. Боти обходять інтернет у пошуках елементів <form> і наосліп їх надсилають. Чим займається ваша компанія, їм байдуже. А форма, що надсилає лист на кожну заявку, приваблює ще й тих, хто хоче розсилати пошту ніби від вашого імені.

Добра новина в тому, що більшість ботів примітивні. Вони заповнюють усі поля, надсилають миттєво і повторюють. Таку поведінку легко розпізнати, не змушуючи людей розв’язувати головоломки.

Шари, через які заявка проходить на сервері: ліміт розміру, ліміт частоти, валідація, перевірка honeypot, безпечна доставка
Шари, через які заявка проходить на сервері: ліміт розміру, ліміт частоти, валідація, перевірка honeypot, безпечна доставка

Зупиніть ботів, не караючи людей

Спершу ставимо дешеві перевірки, а тертя для користувача додаємо, лише коли сайт справді цього потребує.

Додайте honeypot-поле

Honeypot - поле, яке люди не бачать, а боти заповнюють. Якщо в ньому є значення, це бот. Хитрість у тому, щоб відповісти звичайним повідомленням про успіх: так бот нічого не дізнається.

<!-- Візуально приховане, пропускається клавіатурою і скрінрідерами -->
<div class="visually-hidden" aria-hidden="true">
  <label for="website">Website</label>
  <input id="website" name="website" tabindex="-1" autocomplete="off">
</div>

На сервері непорожнє поле website отримує таку саму успішну відповідь, як справжня заявка. Нічого не зберігається, і ніхто не отримує сповіщення.

Обмежуйте частоту за IP, не зберігаючи IP

Обмежте, скільки заявок одне джерело може надіслати за певний час, наприклад кілька за десять хвилин. Зберігайте солений хеш IP, а не саму адресу. Так ви маєте захист від зловживань і не тримаєте зайвих персональних даних.

Перевірку-челендж - лише коли вона потрібна

Якщо сайт атакують розумніші боти, додайте ненав’язливу перевірку на кшталт Cloudflare Turnstile чи hCaptcha. Де можливо, вмикайте невидимий або керований режим і переконайтеся, що запасний варіант працює з клавіатурою і скрінрідером. Головоломка ніколи не повинна бути першою лінією захисту.

Перевіряйте все на сервері

Валідація в браузері - для зручності користувача. Безпекою вона не є, бо бот може надіслати будь-який запит. Сервер має ще раз перевірити кожне поле, як радить шпаргалка OWASP з валідації введення.

Добра валідація сувора і нудна:

  • Дозволяйте лише відомі поля. Невідомі ключі відхиляйте, а не передавайте далі.
  • Обмежуйте довжину. Імені не потрібно 5 000 символів. Повідомленню рідко треба більше 2 000.
  • Перевіряйте формат. Email має виглядати як email. Поля вибору приймають лише значення зі списку.
  • Обмежуйте розмір запиту ще до розбору, щоб ніхто не надіслав величезне тіло.
// Серверна схема, спільна з формою в браузері
import { z } from "zod";

export const ContactSchema = z.object({
  name: z.string().trim().min(1).max(120),
  email: z.string().trim().email().max(254),
  company: z.string().trim().max(160).optional(),
  budget: z.enum(["5k-10k", "10k-25k", "25k-50k", "50k-plus", "not-sure"]),
  message: z.string().trim().max(2000).optional(),
  consent: z.literal(true),
  website: z.string().max(200), // honeypot: перевіряється після валідації
}).strict();

Одна схема в браузері і на сервері робить повідомлення про помилки однаковими. Але рахується саме серверна копія.

Блокуйте ін’єкції та зловживання

Валідація обмежує, що потрапляє всередину. Безпечна обробка визначає, що це введення може зробити далі.

  • Ніколи не вставляйте введення користувача в заголовки листа. Перенесення рядка в полі «ім’я» може додати отримувачів, якщо потрапить у заголовок To чи Subject. Надсилайте сповіщення на фіксовану адресу, а текст користувача - лише в тілі.
  • Надсилайте сповіщення простим текстом. Якщо заявки йдуть у Slack, Telegram чи пошту, відправляйте їх як plain text. Рендеринг введення як HTML чи markdown відкриває двері для підкинутих посилань і скриптів.
  • Екрануйте під час виведення. Будь-яка адмін-сторінка зі списком заявок має екранувати контент, щоб скрипт із повідомлення не запустився у вашому браузері.
  • Використовуйте параметризовані запити. Зберігайте заявки через ORM або prepared statements, а не склеюючи SQL-рядки.
  • Перевіряйте походження запиту. Приймайте заявки лише з origin вашого сайту і з очікуваним content type. Варіанти описані у шпаргалці OWASP щодо CSRF.

Це ті самі принципи, що й у нашому чеклісті безпеки сайту, застосовані до тієї частини сайту, яка приймає введення.

Не допустіть витоку даних із заявок

Форма - це конвеєр даних. Кожне місце, куди потрапляє заявка, - потенційне джерело витоку.

  1. Збирайте менше. Кожне необов’язкове поле - це дані, які треба захищати. Питайте лише те, що потрібно для відповіді.
  2. Знайте кожен пункт призначення. База, пошта, CRM, сповіщення в месенджер. Перелічіть їх і перевірте, хто має доступ до кожного.
  3. Тримайте секрети на сервері. Ключі API до CRM чи сервісу сповіщень ніколи не мають потрапляти в код браузера.
  4. Не логуйте тіла запитів. Логи помилок із повними запитами в підсумку зберігають персональні дані в інструменті, який ніхто не перевіряє.
  5. Встановіть строк зберігання. Видаляйте або архівуйте старі заявки за графіком.
  6. Перевірте обробників. Сторонні сервіси форм і CRM обробляють персональні дані від вашого імені, тож з ними потрібні договори.

Згоду і приватність, зокрема що писати біля кнопки надсилання, ми розбирали в статті про GDPR для сайту.

Куди йде заявка після валідації: база даних, сповіщення команді і CRM, кожне зі своїм контролем доступу
Куди йде заявка після валідації: база даних, сповіщення команді і CRM, кожне зі своїм контролем доступу

Як ми робимо форми в Kyvrel

Наша власна форма заявки працює в такому самому порядку, як і форми, які ми робимо для клієнтів. Коротко, серверний обробник робить таке:

  1. Відхиляє все, окрім POST.
  2. Відхиляє тіла понад 16 КБ ще до розбору.
  3. Застосовує ліміт частоти за солоним хешем IP.
  4. Розбирає JSON і валідує його за спільною схемою.
  5. На спрацювання honeypot повертає звичайну успішну відповідь, нічого не зберігаючи й не надсилаючи.
  6. Зберігає заявку, а потім надсилає сповіщення простим текстом.

Кожен крок покритий тестом. Ще ми перевіряємо форму з клавіатурою і скрінрідером, бо безпечна форма, якою частина людей не може скористатися, однаково зламана.

Запустіть форму, крізь яку проходять лише справжні заявки

Якщо поточна форма засипає пошту спамом або ніхто не знає, куди йдуть заявки, це варто виправити до наступної кампанії. Безпечні форми - стандарт у кожному сайті, який ми здаємо. Чат-бот - ще одна точка введення даних, і там так само є спам, зловживання промптами й персональні дані, які треба захистити. Ті самі правила діють, якщо ви додаєте чат-бот для сайту. Щоб порахувати вартість із вашим обсягом, мовами й опціями, скористайтеся нашим калькулятором вартості сайту.

Чат-бот із ШІ для сайту

Чат-асистент для вашого сайту, що відповідає з вашого контенту й передає розмову людині.

від12 000 $

7-8 тижнів2 раунди правок на етапДжерел знань у пакеті: 2

  • Правила відповідей: на що бот відповідає, від чого відмовляється й коли кличе людину
  • Віджет чату в стилі вашого сайту для десктопа й мобільних
  • Відповіді лише з ваших джерел знань, з посиланнями на них
  • Збір заявок у розмові з передачею на пошту або в CRM
  • Передача розмови людині поштою разом із перепискою