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