Безопасность7 мин чтения

Коды 2FA не приходят на почту: блокировка входа

Двухфакторный код в спаме — это не просто задержка. Это полная блокировка аккаунта. Пользователь не может войти, не может восстановить доступ, и винит в этом ваше приложение.

Письма с 2FA кодами находятся на пересечении нескольких проблемных зон доставки. Они короткие, срочные, содержат цифры и отправляются повторно. Каждый из этих признаков срабатывает на спам-эвристики, которые фильтры совершенствовали годами.

Когда код попадает в спам, пользователь не входит вообще. Нет никакой graceful degradation. Нет возможности «повторить попытку после перезагрузки». А учитывая, что код живёт 5–10 минут, даже малейшая задержка доставки — это практически гарантированный отказ в доступе.

Кратко

Коды 2FA — критичный путь. Код в спаме останавливает ваше приложение полностью. Отправляйте их с отдельного, максимально защищённого поддомена, с собственным DKIM и жёсткой инфраструктурой. Это не часть маркетинговой рассылки.

Какие эвристики спама срабатывают против 2FA

  • Короткое тело письма. «Ваш код подтверждения: 382910. Срок действия 10 минут.» Две строки, одна цифра, слово «срочно». Выглядит как учебный пример фишингового письма, на котором учили байесовский классификатор.
  • Код в строке темы. «Ваш код: 382910» запускает anti-phishing эвристику в Gmail, которая специально ловит строки похожие на учетные данные в теме письма.
  • Быстрые повторные отправки. Пользователь три раза кликнул «выслать код заново» — вы отправили три почти идентичных короткихписьма с одного адреса одному получателю за 60 секунд. Это срабатывает на частотные эвристики.
  • Язык срочности. «подтвердить», «защита», «истекает», «немедленно» — все эти слова есть в фишинговых базах знаний фильтров.
Пользователь винит приложение, а не спам-фильтр

Когда 2FA не работает, пользователь не думает «спам-фильтр съел письмо». Он думает «приложение говно». Он удаляет приложение, оставляет отрицательный отзыв или инициирует chargeback. Цена одного упущенного кода 2FA измеряется потеряными пользователями и проблемами с репутацией, а не тикетами в поддержку.

Как измерять размещение 2FA на практике

Запустите боевую цепочку 2FA на seed-ящики, зафиксируйте размещение по каждому провайдеру и время доставки. Код, который пришёл через 3 минуты после истечения 5-минутного срока действия, бесполезен, даже если технически он в инбоксе.

# Триггерим 2FA на seed-адреса
for seed in seeds.list(group='2fa-test'):
  start = time.now()
  trigger_2fa(seed.address)
  delivery = poll_placement(seed.address, timeout=120)
  print({
    "provider": seed.provider,
    "folder": delivery.folder,
    "seconds": (delivery.arrived_at - start).total_seconds()
  })

# Падаем при:
# - любой seed в "спаме"
# - доставка > 30 секунд

Приемлемые метрики

  • Размещение. 99%+ в инбоксе на Gmail, Outlook, Yahoo, iCloud.
  • Латенция. Менее 15 секунд на p95, менее 30 секунд на p99.
  • Доставка при переотправке. То же размещение и та же скорость при второй и третьей отправке одному и тому же получателю.

Исправления в порядке убывания влияния

  1. Отдельный поддомен и отправитель. auth.yourapp.com с собственным DKIM-селектором. Никогда не делитесь с маркетингом и уведомлениями.
  2. Переделайте шаблон письма. Добавьте контекст, которого нет в фишинговых письмах: имя пользователя, название браузера или устройства, из которого идёт попытка входа, город по IP. Это отличает легитимную 2FA от фишинга уже в теле письма.
  3. Не кладите код в тему письма. Тема: «Запрос входа в ваш аккаунт». Код в теле. Gmail'ская anti-phishing эвристика, которая ловит коды в темах, будет срабатывать, если вы положите код там.
  4. Добавьте text/plain версию. HTML-only письма выглядят тощими. Добавьте простотекстовую часть с кодом, одной строкой объяснения и контактом поддержки.
  5. Используйте выделенный IP если позволяет объём. Шареные IP у транзакционных ESP портят репутацию через других клиентов — один плохо настроенный аккаунт на том же IP может полностью уронить ваше размещение 2FA на час.
Отправляйте TOTP параллельно с email

Email 2FA не должна быть единственным вторым фактором. Предложите TOTP (Google Authenticator, Authy) как основную опцию, а email как fallback. TOTP имеет нулевой риск доставки. Для критичных аккаунтов добавьте WebAuthn.

Шаблон, который попадает в инбокс

Тема: Запрос входа из Chrome на macOS (Москва, Россия)

Привет {{first_name}},

Мы получили запрос входа в ваш аккаунт из:
  Браузер: Chrome 121 на macOS
  Место: Москва, Россия (примерно, по IP)
  Время: {{timestamp_iso}}

Если это были вы, введите этот код на странице входа:

    {{code}}

Код действует до {{expiry_iso}} ({{expiry_human}}).

Если вы НЕ пытались входить, срочно смените пароль:
https://yourapp.com/account/security

--
Служба безопасности {{app_name}}
ул. Примерная, 123, Москва
support@yourapp.com

Обратите внимание: полнотелое письмо, контекст запроса входа, имя команды, физический адрес, обычные URL. По структуре полная противоположность фишингу, несмотря на наличие в письме одноразового кода.

Проверка инфраструктуры

  • SPF ~all, а не -all изначально. Если вы пропустите один include, hard fail (-all) будет отклонять легитимную 2FA. Начните с soft fail, мониторьте DMARC отчёты, потом переходите на -all когда всё чисто.
  • DKIM ключ 2048 бит. 1024-битные ключи всё ещё работают, но всё больше штрафуются Gmail'ом и Outlook'ом.
  • DMARC p=quarantine или p=reject. Отсутствие DMARC политики — это handicap доставки для критичной аутентификационной почты.
  • MTA-STS и TLS reporting. Опубликуйте _mta-sts.yourapp.com. Провайдеры всё больше требуют TLS-protected доставку для транзакционной почты.
Тестируйте после каждого изменения шаблона

Шаблон 2FA переделывается чаще, чем кажется — i18n, ребрендинг, юридический footer. Каждое из этих изменений может привести к регрессии размещения. Подключите автоматический тест в CI auth-сервиса.

→ Запустить бесплатный Inbox Placement Test

Частые вопросы

Почему первый код приходит, а переотправки нет?

Frequency-based filtering. Всплеск идентичных коротких писем от одного отправителя к одному получателю за 60 секунд срабатывает на частотные эвристики. Решение: увеличьте интервал между переотправками или добавьте в каждое письмо переменный токен, чтобы изменить content-hash.

SMS 2FA коды лучше?

По доставке — да, но SMS имеет свои проблемы: SIM-swap атаки, дороговизна международной доставки и фрикция пользователя. Правильный дизайн: TOTP основной, email или SMS fallback.

Помогут ли более длинные коды?

Более длинные коды сложнее фишить, но имеют ту же доставку в email. Проблема размещения — это шаблон и отправитель, а не длина кода.

Нужна ли отдельная ESP для 2FA?

Да, если объём это позволяет. Отдельная ESP, отдельный поддомен, отдельный IP. Изоляция защищает критичную auth-почту от ошибок маркетинга.
Related reading
Found this useful? Share it
AB
Об авторе
Artem Berezin
B2B Deliverability Specialist

B2B deliverability specialist with 5+ years of hands-on outreach experience. Built campaigns reaching 90,000+ inboxes across 20+ countries — and fixed the deliverability problems that came with that scale.

Проверьте доставляемость в 20+ провайдерах

Gmail, Outlook, Yahoo, Mail.ru, Яндекс, GMX, ProtonMail и другие. Реальные скриншоты входящих, SPF/DKIM/DMARC, вердикты спам-фильтров. Бесплатно, без регистрации.

Запустить тест →

Тесты без ограничений · 20+ ящиков · Живые результаты · Аккаунт не нужен