Выбор ответа Senior Безопасность бэкенда обновлено

Сравнение секретов и timing attack

Вопрос

Вебхук платёжной системы подписан HMAC. Сервис проверяет if (signature === expected). В чём проблема и как правильно?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: === выходит на первом несовпадении; нужен crypto.timingSafeEqual. Посимвольное сравнение с ранним выходом теоретически позволяет подбирать подпись по байту, измеряя время ответа.

Варианты ответа

  1. Проблемы нет, === для строк работает за постоянное время
  2. === выходит на первом несовпадении; нужен crypto.timingSafeEqualправильный ответ
  3. Нужно сравнивать через ==, чтобы учесть разные типы
  4. Хешировать обе строки MD5 и сравнить хеши через ===

Разбор

Посимвольное сравнение с ранним выходом теоретически позволяет подбирать подпись по байту, измеряя время ответа. По сети эффект мал, но защита стоит одну строку: crypto.timingSafeEqual(Buffer.from(a), Buffer.from(b)). Важная деталь: функция бросает исключение при разной длине буферов, поэтому длину проверяют заранее (длина подписи не секрет) или сравнивают HMAC от обеих строк.

== только добавляет приведение типов. Хеширование MD5 перед === сильно усложняет атаку (атакующий не управляет префиксом хеша), но это обходной путь, а не стандартное решение; стандарт это timingSafeEqual.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.

Термины по теме