Увидеть “email signed by” в Gmail (или аналогичные визуальные подсказки в других клиентах) — это напоминание о том, что идентичность и целостность имеют значение в рабочих процессах электронной почты. Но если вы получаете входящую почту через вебхуки (для автоматизации QA, верификации регистрации или LLM-агентов), граница безопасности смещается: ваш реальный риск часто заключается не в том, была ли у SMTP-сообщения подпись DKIM, а в том, является ли подлинным HTTP-запрос, доставляющий обработанное письмо.
В этом руководстве объясняется, что на самом деле означает “email signed by”, почему этого недостаточно для автоматизации на основе вебхуков, и как проверить подлинность данных вебхука способом, который выдержит повторные попытки, дубликаты и враждебный ввод.
Если вы используете именно Mailhook, он поддерживает уведомления вебхуков в реальном времени и подписанные данные для полученных писем в виде структурированного JSON. Для каноничного, актуального контракта интеграции (точные заголовки, построение подписи и примеры) используйте: mailhook.co/llms.txt.
Что на самом деле означает “Email Signed By”
Большинство интерфейсов почтовых ящиков показывают “signed by”, когда сообщение прошло проверки криптографической аутентификации, обычно DKIM (DomainKeys Identified Mail). DKIM позволяет отправляющему домену подписывать части сообщения, чтобы получатели могли обнаружить подделку при передаче и связать сообщение с доменом.
Важный нюанс:
- DKIM помогает получателю ответить на вопрос “Вероятно ли, что это сообщение исходит от авторизованного отправителя для этого домена, и было ли оно изменено при передаче?”
- DKIM не аутентифицирует HTTP-запрос, который ваша система получает позже от провайдера вебхуков.
Даже если сообщение идеально подписано DKIM, злоумышленник все равно может попытаться:
- Подделать вашу конечную точку вебхука с поддельными данными “получено новое письмо”
- Повторно отправить более старые действительные данные для повторного запуска OTP-потока
- Подделать JSON-поля, если ваша проверка не вычисляется по необработанному телу
Поэтому рассматривайте “email signed by” как полезный контекст для самого письма, но не как замену аутентификации вебхука.
DKIM против подписей вебхуков: две разные проблемы доверия
| Механизм | Что он аутентифицирует | Где применяется | От чего не защищает |
|---|---|---|---|
| DKIM (показывается как “email signed by”) | Части сообщения электронной почты, подписанные доменом | SMTP и получение в почтовый ящик | Поддельные HTTP-вызовы вебхуков, повторные доставки, ваш собственный конвейер парсинга/нормализации |
| Подпись вебхука | Тело HTTP-запроса, доставленное в вашу конечную точку | Граница вашего приложения | “Легитимное” письмо, содержащее вредоносный контент (инъекция промптов, SSRF-ссылки и т.д.) |
Лучшая практика в автоматизации — проверять и то, и другое:
- Проверить подпись вебхука, чтобы доказать, что запрос пришел от вашего провайдера.
- Обращаться с содержимым электронной почты как с недоверенным вводом даже после проверки вебхука.
Для справки по стандартам DKIM см. RFC 6376.
Модель угроз: от чего вы защищаетесь
Когда ваша система получает входящую почту в виде JSON через вебхук, предполагайте, что злоумышленники попробуют распространенные режимы сбоев, которые также выглядят как нормальное поведение распределенных систем:
- Подделка: отправка запросов напрямую к вашей конечной точке вебхука
- Повтор: повторная отправка ранее действительного запроса для повторного запуска побочных эффектов
- Подделка тела: эксплуатация фреймворков, которые повторно сериализуют JSON и случайно проверяют другое байтовое представление
- Путаница заголовков: полагание на IP-списки разрешений или строки “User-Agent” вместо криптографической проверки
- Усиление повторов: запуск множественных нисходящих действий, потому что ваш обработчик не идемпотентен
Если ваш нисходящий потребитель — LLM-агент, ставки выше: поддельное или повторенное письмо может стать инъекцией инструкций или заставить агента повторно отправлять письма верификации, кликать по ссылкам или эксфильтрировать секреты.
Что должно означать “проверить подлинность данных вебхука” на практике
Безопасный поток проверки вебхука обычно включает все следующее:
1) Проверить подпись, вычисленную по необработанному телу запроса
Единственная последовательность байтов, с которой могут согласиться обе стороны, — это необработанное тело HTTP-запроса. Многие нарушения вебхуков происходят из-за проверки обработанного объекта (или красиво отформатированной JSON-строки), а не точных полученных байтов.
Правила реализации:
- Захватывайте необработанные байты тела, как только их получает ваш фреймворк.
- Вычислите ожидаемую подпись, используя ваш секрет вебхука.
- Сравните подписи, используя сравнение с постоянным временем.
Как строятся подписи, зависит от провайдера (HMAC, отдельный JWS, асимметричная подпись). Не угадывайте имена заголовков или правила канонизации.
Mailhook предоставляет подписанные данные для уведомлений вебхуков, но вы должны следовать точному контракту в mailhook.co/llms.txt.
2) Принудительно установить допуск временной метки для снижения риска повтора
Одна подпись доказывает подлинность, но не свежесть.
Добавьте требование временной метки:
- Требуйте заголовок временной метки или поле, предоставленное провайдером.
- Отклоняйте запросы старше небольшого окна (обычно 5 минут, иногда от 1 до 15 минут в зависимости от повторов и очередей).
- Учитывайте смещение часов и устанавливайте явный допуск.
Если вы должны поддерживать более длительные задержки, комбинируйте проверки временных меток с хранением повторов (следующий раздел).
3) Добавить обнаружение повторов с использованием ID доставки
Даже легитимные провайдеры повторяют вебхуки. Злоумышленники тоже повторяют.
Поэтому ваш обработчик должен:
- Извлечь стабильный идентификатор события (ID доставки, ID события, ID сообщения или специфичный для провайдера ключ идемпотентности).
- Сохранить его с TTL в быстром хранилище данных.
- Отклонить или проигнорировать дубликаты.
Это не опционально, если ваш вебхук запускает побочные эффекты (отметка OTP как потребленного, создание аккаунта, одобрение рабочего процесса).
4) Сбой в закрытом состоянии и разделение “проверки” и “обработки”
Чистый дизайн:
- Слой проверки: подпись, временная метка, проверки повторов
- Слой обработки: парсинг JSON, дедупликация по сообщению/артефакту, извлечение OTP или ссылки, постановка в очередь работы
Если проверка не удается:
- Возвратить 4xx (часто 401/403) и не ставить в очередь.
Если обработка не удается:
- Возвратить 2xx только после того, как вы безопасно сохранили событие для повтора, или возвратить 5xx, чтобы провайдер повторил попытку. Выбирайте намеренно.
5) Держать секреты вне логов и защищать конечную точку
Минимальная гигиена:
- Хранить секреты вебхуков в менеджере секретов.
- Ротировать секреты и поддерживать двойную проверку во время ротации.
- Использовать только HTTPS.
- Не логировать необработанные подписи, секреты или полные тела писем в общих логах.
Чеклист проверки, независимый от провайдера (копирование/вставка для code review)
Используйте это как врата проверки, прежде чем позволить агентам или CI-конвейерам доверять событиям входящей почты:
- Необработанное тело захвачено и используется для проверки подписи
- Проверка подписи выполняется с постоянным временем
- Временная метка требуется и проверяется с определенным допуском
- Защита от повторов существует с использованием стабильного идентификатора доставки
- Обработчик идемпотентен на уровне побочных эффектов
- Непроверенные запросы никогда не достигают нисходящих процессоров
- Содержимое электронной почты обрабатывается как недоверенный ввод (без рендеринга HTML, списки разрешений ссылок, минимальное извлечение артефактов)
Референсная архитектура: вебхук в первую очередь с резервным опросом
Доставка вебхука — это способ получения входящей почты с наименьшей задержкой, но производственные системы должны быть устойчивы к случайным сбоям доставки.
Общий паттерн в системах почтовых ящиков, ориентированных на автоматизацию:
- Вебхук срабатывает быстро, когда приходит письмо.
- Ваш обработчик проверяет подлинность, сохраняет запись и ставит работу в очередь.
- Если вебхук пропущен или задержан, ваш рабочий процесс может опрашивать API почтового ящика как резерв.
Mailhook поддерживает как уведомления вебхуков, так и API опроса, что полезно для детерминированного QA и рабочих процессов агентов, где вы хотите “сначала push, потом pull как резерв”.

Практические заметки для LLM-агентов: подлинность необходима, но недостаточна
Даже идеально аутентифицированные вебхуки могут доставлять враждебный контент, потому что злоумышленники могут отправлять реальные письма в ваши одноразовые почтовые ящики.
Для безопасности агентов:
- Предпочитайте минимизированное JSON-представление (тема, отправитель, время получения и извлеченный артефакт), а не необработанный HTML.
- Избегайте разрешения агентам “просматривать” произвольные ссылки, найденные в электронной почте.
- Добавьте списки разрешений хостов для ссылок верификации (и рассмотрите разрешение перенаправлений на стороне сервера со строгими правилами).
- Установите строгие бюджеты на действия агентов (никаких повторяющихся циклов “переслать код”).
Вот где структурированная доставка JSON помогает: она упрощает создание детерминированных, минимальных экстракторов вместо хрупкого скрапинга HTML.
Пример псевдокода (структура, не специфичная для провайдера)
Цель — показать поток управления без придумывания деталей провайдера.
raw_body = getRawRequestBodyBytes(req)
sig = req.headers["Signature"]
timestamp = req.headers["Signature-Timestamp"]
if !sig or !timestamp:
return 401
if isTooOld(timestamp, toleranceSeconds=300):
return 401
expected = computeSignature(secret, timestamp, raw_body)
if !constantTimeEquals(sig, expected):
return 403
delivery_id = parseJson(raw_body).delivery_id
if seenRecently(delivery_id):
return 200 // идемпотентное принятие
markSeen(delivery_id, ttl=24h)
enqueueForProcessing(raw_body)
return 200
Чтобы реализовать это правильно для Mailhook (фактические имена заголовков, как строится подписанная строка и какие ID доступны), следуйте контракту в mailhook.co/llms.txt.
Где подходит Mailhook (не изменяя вашу позицию безопасности)
Mailhook разработан для рабочих процессов, где электронная почта является входом для программных систем, включая LLM-агентов и автоматизацию QA:
- Создание одноразовых почтовых ящиков через API
- Получение входящих писем как структурированный JSON
- Получение уведомлений вебхуков в реальном времени (плюс опрос как резерв)
- Проверка подлинности с подписанными данными вебхуков
- Использование общих доменов мгновенно или подключение пользовательского домена, когда нужен более жесткий контроль
Если вы создаете конвейер “электронная почта как поток событий”, критический вывод: обращайтесь с вашим вебхуком как с публичной поверхностью API. Проверка “email signed by” на уровне электронной почты полезна, но проверка подлинности данных вебхука — это то, что защищает ваши автоматизации.
Для деталей реализации, примеров и канонического контракта интеграции начните здесь: Mailhook llms.txt.