Проверка HMAC-подписи webhook: как сделать правильно
Что на самом деле доказывает HMAC
Точная схема, которую использует Olmira
X-Aether-Signature, X-Aether-Webhook-Id и X-Aether-Event. (Префикс заголовка — Aether, а не Olmira: это наследие внутреннего кодового названия платформы; на работу схемы это никак не влияет, меняется только буквальное имя заголовка.)Проверка доставки простыми словами
crypto покрывает всё это без единой зависимости; именно в предварительных проверках ниже корректные реализации на самом деле и отличаются от сломанных.Ошибки, из-за которых проверка не проходит
., — вторая по частоте, и её легко допустить, потому что тело — более «очевидное», что хочется хешировать.Прежде чем доверять этому в продакшене
Сначала проверьте окно временных меток
Отклоняйте всё, что выходит за небольшой допуск (Olmira публикует 300 секунд, то есть пять минут, как собственное ориентировочное значение), прежде чем тратить время процессора на хеширование: устаревшая подпись не заслуживает сравнения.
Сравнивайте за постоянное время
Используйте примитив сравнения за постоянное время из вашего языка, а не обычную проверку на равенство, чтобы несовпадение никогда не выдавало по времени, насколько близкой была догадка.
Убедитесь, что вы хешируете сырое тело запроса
Хотя бы один раз во время настройки запишите в лог точную строку, которую ваш код собирается хешировать, и сравните её побайтово с тем, что реально прислала тестовая доставка.
Учтите смену секретного ключа
Где бы вы ни хранили секрет, сделайте его замену однострочным изменением конфигурации: если ротировать его в панели управления и не обновить в тот же момент, все доставки начнут падать, пока вы не догоните.
Как это устроено в Olmira
Исходящие IP-адреса меняются — за балансировщиками нагрузки, при изменениях инфраструктуры провайдера, просто со временем, — и белые списки по ним на практике оказываются хрупкими. Криптографическая подпись подтверждает подлинность независимо от сетевого маршрута, а это более надёжная и стабильная гарантия, чем «запрос пришёл из диапазона, который мы сегодня распознали».
Нет — схема везде одинаковая. По каждому эндпоинту различается только сам секрет, потому что каждый генерируется независимо.
Нет — проверьте подпись, быстро подтвердите приём, а всё медленное (запись в базу данных, обращения к другим системам) выполняйте асинхронно после этого. Отправитель вебхуков, у которого истечёт время ожидания вашей конечной точки, обычно сочтёт это сбоем и повторит доставку, а вам не нужно вызывать это медлительностью, а не настоящей ошибкой.
Отклоняйте до любой другой обработки — ответ 4xx и ничего больше. Не описывайте в теле ответа, почему проверка не прошла; атакующий, зондирующий ваш эндпоинт, не должен бесплатно получать сведения о том, какая часть подделанной подписи была неверной.