Атака, которую никто не видит, приходит через форму обратной связи
Форма обратной связи кажется безобидной. Это самая открытая дверь на сайте, и почти никто её не запирает.
Все защищают вход в систему. На форму обратной связи не смотрит никто. А ведь она принимает ввод от кого угодно. Без аутентификации, без трения, часто даже без ограничения на число отправок.
Именно эту асимметрию ищет атакующий. Текстовое поле, которое разговаривает с почтовым сервером, с базой данных или с внутренним вебхуком. Ты видишь поле «сообщение». Он видит командную строку.
Почему эта цель так привлекательна
Форма обратной связи собирает в одном месте три редких свойства. Она принимает недоверенный ввод. Запускает логику на сервере. И почти никогда не проверяется. Разработчик убедился, что сообщение доходит до почты. На этом остановился.
Проблема в том, что за фразой «сообщение доходит до почты» скрывается целый путь. Текст пользователя вставляется в заголовок SMTP, склеивается в запрос или уходит в сторонний сервис. Каждая из этих границ — возможность для инъекции.
Инъекция почтовых заголовков
Классический случай называется email header injection. Если ты берёшь поле «тема» или «отправитель» и вставляешь его прямо в заголовок письма, атакующий пишет перенос строки и добавляет свои заголовки. Например, скрытую копию на тысячу адресов.
И вот твой сервер уже рассылает спам. Не от твоего имени случайно, а буквально через твою инфраструктуру, с твоим IP и твоим доменом. Итог предсказуем: крупные провайдеры помечают домен как источник спама, и рабочая почта перестаёт куда-либо доходить.
Текст, который становится кодом
Дальше идут сценарии похуже. Если ты сохраняешь сообщение в базу без параметризации запроса, ты открываешь дверь SQL-инъекции. Если показываешь сообщение в админ-панели без экранирования HTML, атакующий сажает скрипт, который запустится в браузере твоей команды при открытии заявки. Это хранимый XSS, один из самых недооценённых векторов.
Обрати внимание на схему. Ни в одном из этих случаев атакующий никуда не «вламывался». Он использовал форму ровно так, как она задумана. Уязвимость — не какая-то экзотическая дыра. Это отсутствие простого правила: никогда не доверяй тому, что приходит извне.
Что делать, по порядку приоритета
Тебе не нужен ни WAF, ни консультант по безопасности, чтобы закрыть 90% этого. Нужна дисциплина в четырёх пунктах.
- Проверяй на сервере, а не только в браузере. Валидация на фронтенде — это удобство для пользователя, а не защита. Атакующий не пользуется твоей формой, он делает POST прямо на эндпоинт.
- Экранируй на выходе, всегда. При записи в базу используй параметризованные запросы. При выводе в панель экранируй HTML. Считай каждое сообщение враждебным, пока не доказано обратное.
- Отклоняй переносы строк в полях заголовка. У темы, имени и почты нет причин содержать \r или \n. Отфильтруй их до того, как коснёшься SMTP.
- Ограничь частоту отправок и добавь невидимую проверку. Rate limiting по IP плюс honeypot или hCaptcha останавливают ботов, не портя опыт живого человека.
И то, о чём почти все забывают
Форма обратной связи собирает персональные данные. Имя, почту, часто телефон и содержимое сообщения. Это ставит тебя под действие GDPR, нравится тебе или нет. Нужна правовая основа для обработки этих данных, а согласие должно быть информированным.
На практике это три конкретные вещи. Понятное уведомление о конфиденциальности рядом с формой. Определённая правовая основа — обычно законный интерес по статье 6 или явное согласие. И политика хранения, потому что держать заявки вечно — не стратегия, а накапливающаяся ответственность. Если у тебя украдут базу заявок, проблема перестаёт быть технической и становится регуляторной.
Безопасность формы — это не дорогой файрвол. Это отказ доверять тексту, который написал незнакомец.— Krivar Diário
Мораль скучная, и потому она работает. Атака, которую никто не видит, приходит через дверь, на которую никто не смотрит. Относись к форме обратной связи с тем же уважением, что и ко входу в систему, и большинство этих проблем просто не случится.