Состояние гонки (race condition) — ошибка, при которой результат работы программы зависит от порядка выполнения параллельных операций, и атакующий может «вклиниться» между проверкой и действием, которое на неё опирается.
Как возникает состояние гонки
Современные программы делают многое параллельно: потоки, процессы и запросы совместно используют файлы, память и записи в базе данных. Если код сначала что-то проверяет, а затем действует двумя отдельными шагами, состояние между ними может измениться. Этот классический шаблон называют TOCTOU (time-of-check to time-of-use, CWE-367), а общую слабость — CWE-362.
Примеры:
- Привилегированная программа проверяет, что файл безопасен, и открывает его, а атакующий в промежутке подменяет его символической ссылкой на системный файл.
- Интернет-магазин проверяет, что подарочный сертификат не использован, и списывает его; множество одновременных запросов позволяет списать его несколько раз (limit overrun).
- В ядре два потока освобождают или меняют один и тот же объект, что приводит к повреждению памяти, например use-after-free.
Почему это важно
Состояния гонки трудно найти при тестировании: они проявляются только при определённых таймингах, но атакующий может надёжно их вызывать, повторяя попытки. Ошибка Dirty COW в ядре Linux (CVE-2016-5195) позволяла любому локальному пользователю получить root через гонку в работе с памятью и использовалась в реальных атаках, в том числе на Android. Многие уязвимости локального повышения привилегий в Windows и Linux — это состояния гонки, а в веб-приложениях они открывают путь к финансовому мошенничеству. Наряду с переполнением буфера это одни из самых технически сложных классов уязвимостей.
Как предотвратить
- Использовать атомарные операции, блокировки и транзакции базы данных с ограничениями.
- Избегать раздельных шагов «проверить — использовать» для файлов: работать с дескрипторами, а не путями.
- Делать чувствительные веб-операции идемпотентными и ограничивать частоту запросов.
- Тестировать с помощью инструментов для конкурентности, фаззеров и thread sanitizer.