Используйте HTTPS и проверяйте подпись по протоколу отправителя до обработки события. Для HMAC важны общий секрет, точные исходные байты и безопасное сравнение. Дополнительно проверяют временную метку и повтор события, если это предусмотрено протоколом. Одна подпись не мешает повторно прислать ранее подписанное сообщение.
Как проверить подлинность и целостность webhook и защитить его передачу?
HMAC или цифровая подпись проверяют сообщение, HTTPS защищает канал, а от повторов нужны отдельные меры.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
HTTPS защищает данные в пути и позволяет отправителю проверить сервер. Но для входящего webhook обычно нужна ещё проверка, что сообщение действительно сформировано ожидаемым поставщиком.
Если поставщик использует HMAC, получатель пересчитывает его с общим секретом. Подписывается именно предусмотренная протоколом последовательность байтов: это может быть исходное тело вместе с временной меткой. Нельзя сначала разобрать JSON и сериализовать его заново — пробелы и порядок полей способны изменить подпись.
Упрощённый пример для вымышленного протокола, где HMAC-SHA256 подписывает только тело:
import hashlib
import hmac
def verify(secret: bytes, body: bytes, signature: str) -> bool:
try:
received = bytes.fromhex(signature)
except ValueError:
return False
if len(received) != hashlib.sha256().digest_size:
return False
expected = hmac.new(secret, body, hashlib.sha256).digest()
return hmac.compare_digest(expected, received)
compare_digest предпочтительнее обычного сравнения для этой задачи. Код — только проверка MAC, не законченная защита webhook.
Подлинный пакет можно повторить. Нужны предусмотренная протоколом проверка свежести и идемпотентная обработка уникального события. Метку времени следует включать в подписанные данные, иначе её можно подменить. Повторная законная доставка не должна повторять бизнес-операцию.
Для асимметричной подписи используют доверенный публичный ключ и библиотеку соответствующего алгоритма, а не тот же HMAC-код. Секреты хранят вне исходников, ограничивают размер запросов и не логируют чувствительные данные.
Провайдерские SDK обычно предпочтительнее самостоятельного угадывания формата. Пример требований к сырым данным и подписям — документация webhook Stripe. После проверки событие надёжно принимают в обработку; порядок и повторы также учитывают.