Почему микросекунды решают всё

В 2019 году исследователь из Google обнаружил, что проверка пароля на сервере занимала ровно 50 миллисекунд для правильной комбинации и 55 — для неправильной. Разница в пять миллисекунд казалась ничтожной. Но атакующий отправил запросы каждые 10 микросекунд и через пару часов восстановил пароль из шести символов.

Сегодня архитектура микросервисов усложнила задачу: один сервис авторизации может стоять за десятью другими, каждый добавляет задержку. Иногда проверка токена занимает больше времени не потому, что он сложный, а потому что база данных сессий загружена. Атакующий это чувствует — и начинает измерять.

Как работает тайминг-атака

Атака по времени (timing attack) использует разницу в скорости выполнения операций. В криптографии есть понятие «постоянного времени» — алгоритм должен выполнять одну и ту же последовательность шагов независимо от входных данных. Если сравнение двух байтов пароля вычисляется быстрее, когда они совпадают, а медленнее — когда нет, это уже риск.

В API микросервисов чаще всего проверяют токен по схеме:

  1. Присутствует ли токен в заголовке запроса?
  2. Не истёк ли срок действия?
  3. Совпадает ли подпись с ожидаемой?

Если на третьем шаге сравнение происходит «по байтам слева направо», как это делают многие языки по умолчанию, то при первом совпадении функция может завершиться. А если первый байт не совпал — код сразу возвращается в начало цикла или выбрасывает ошибку раньше времени. Для наблюдателя задержка будет разной.

Реальные примеры из практики

В открытом репозитории TriliumNext была найдена уязвимость, когда аутентификация через endpoint /api/login/sync позволяла восстанавливать HMAC-хеш по одному байту за раз. В отчёте о безопасности (CVE) указано, что это критическая уязвимость тайминг-атаки. Исследователи использовали статистический анализ задержек ответа: если сервер ответил быстрее — значит, первый байт совпал. Так злоумышленник собрал хеш целиком и вывел из строя систему аутентификации без прямого доступа к данным.

Ещё один пример — API банка, который проверял JWT-токены с помощью библиотеки jsonwebtoken в Node.js. По умолчанию эта библиотека сравнивает подпись построчно, что создавало временные различия. В 2025 году команда безопасности заменила стандартное сравнение на функцию timingSafeEqual, которая всегда тратит одинаковое время и использует циклы для проверки всех байтов.

Почему это сложно заметить

Проблема не в коде, а в инструментах тестирования. Большинство сканеров уязвимостей проверяют SQL-инъекции, XSS и другие классические проблемы, но тайминг-атаки требуют другого подхода. Нужно измерять задержки с точностью до микросекунд, что делают редко. Даже когда команда тестирует API на проникновение, они часто пропускают этот шаг, считая его «недостаточно важным».

В микросервисной архитектуре сложность возрастает: один сервис может быть написан на Go, другой — на Python, третий — на Java. Каждый из них обрабатывает тайминг по-своему. Если в одном месте используется == для сравнения байтов, а в другом — специальная функция, то поведение системы становится непредсказуемым. Атакующий видит лишь общую задержку ответа от всех сервисов вместе взятых.

Как защитить API от тайминг-атак

Защита строится на двух принципах: постоянство времени и минимизация утечек через другие каналы.

  1. Используйте функции безопасного сравнения. В Python это hmac.compare_digest, в Java — Objects.equals с поправкой на алгоритм, в Go — crypto/subtle.ConstantTimeCompare. Они всегда выполняют одну и ту же последовательность операций независимо от входных данных.

  2. Не полагайтесь только на тайминг-защиту. Даже если сравнение происходит в постоянном времени, атакующий может измерить время отправки запроса до получения ответа через другие каналы: размер тела ответа, код ошибки, доступность сервиса. Поэтому нужно минимизировать утечки по всем каналам сразу.

  3. Валидируйте токены на клиенте или шлюзе. Если проверка происходит на API-шлюзе перед маршрутизацией к микросервисам, то время задержки от одного сервиса не будет видно атакующему как сигнал о совпадении пароля. Шлюз должен отвечать одинаково быстро и в случае ошибки, и в случае успеха.

  4. Мониторьте метрики времени ответа. Если один из микросервисов начинает отвечать медленнее — это может быть признаком нагрузки или попытки атаки по таймингу. Системы мониторинга вроде Prometheus могут собрать статистику задержек и выделить аномалии.

Что будет дальше

Индустрия движется в сторону автоматизации тестирования на проникновение, но инструменты пока не умеют искать тайминг-уязвимости эффективно. Исследователи разрабатывают методы анализа побочных каналов с помощью нейросетей: они обучают модели распознавать узоры в задержках и предсказывать утечки информации даже при малом количестве измерений.

В 2026 году уже появились примеры, когда атакующий использовал не просто сравнение времени ответа, а анализ изменений частоты процессора (Hertzbleed), чтобы вычислять тайминг-различия с точностью до наносекунд. Это говорит о том, что старые методы защиты становятся недостаточными: нужно защищаться от всех каналов утечки сразу — времени, энергии, электромагнитного излучения.

Микросервисы усложнили архитектуру, но не добавили новых типов угроз — они лишь заставили их проявляться чаще. Атакующий теперь может измерять время ответа не от одного сервера, а от цепочки сервисов. И если где-то в глубине стека использовался стандартный оператор сравнения, то вся система становится уязвимой.

Защита требует внимания к деталям, которые обычно остаются незамеченными: как сравниваются байты, какие библиотеки используются для проверки токенов, как настроены таймауты на разных уровнях. И это не просто «настроить правильно», а понять, почему стандартные практики могут привести к утечке информации через время.