Пока антифрод-системы анализируют поведение, а WAF вырезают SQL-инъекции, race condition остаются слепой зоной. Они не оставляют сигнатур, не требуют сложных пейлоадов и работают на уровне бизнес-логики. В 2026 году, с ростом микросервисов и высоконагруженных API, именно конкурентные уязвимости стали причиной громких инцидентов: от многократного начисления бонусов до обхода лимитов на переводы. В этом гайде — всё, что нужно знать пентестеру и разработчику о поиске, эксплуатации и защите от race condition.
Что такое race condition в вебе
Race condition возникает, когда несколько параллельных запросов обрабатываются в непредсказуемом порядке, и приложение не обеспечивает атомарность критических операций. Простейший пример — два одновременных перевода с одного счёта. Если проверка баланса и списание не изолированы, оба запроса могут увидеть достаточный остаток и выполниться, удвоив списание.
В веб-контексте это не классическая гонка потоков внутри одного процесса, а конкуренция HTTP-запросов к одному ресурсу. Типичная цель — состояние гонки между проверкой (check) и действием (use), известное как TOCTOU (time-of-check to time-of-use).
Почему race condition критичны в 2026 году
Классические сценарии эксплуатации
В 2026 году арсенал пентестера пополнился специализированными средствами, заточенными именно под конкурентные атаки.
Смысл метода — отправить несколько запросов так, чтобы сервер начал их обработку максимально одновременно. В Turbo Intruder для этого есть встроенная функция gate. Пример базового скрипта:
python
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=1,
engine=Engine.BURP2
)
# Накапливаем запросы
for i in range(20):
engine.queue(target.req, gate='race')
# Отправляем все разом
engine.openGate('race')
def handleResponse(req, interesting):
if 'success' in req.response:
table.add(req)
Этот скрипт помещает 20 запросов в очередь, а затем открывает «ворота», позволяя им отправиться практически одновременно. Для HTTP/1.1 задержка всё равно будет, но для многих приложений достаточно.
Single-Packet Attack: прорыв 2026 года
HTTP/2 и HTTP/3 позволяют мультиплексировать несколько потоков в рамках одного TCP-соединения, а затем передать их в одном сетевом пакете. Это сводит разницу во времени обработки к наносекундам.
Инструменты:
python
import httpx, asyncio
async def send():
async with httpx.AsyncClient(http2=True) as client:
tasks = [client.post('https://bank.example.com/api/transfer',
json={'amount': 100, 'to': 'attacker'})
for _ in range(5)]
await asyncio.gather(*tasks)
asyncio.run(send())
Если сервер не использует атомарные блокировки, все 5 запросов могут уйти в обработку до того, как баланс будет обновлён.
Как находить потенциально уязвимые точки
При пентесте нужно обращать внимание на:
Разработчикам в 2026 году стоит придерживаться проверенных подходов:
Race condition — это не «баг», а архитектурный просчёт. В 2026 году, когда системы стали ещё более распределёнными, а злоумышленники вооружены single-packet атаками, игнорировать эту поверхность атаки нельзя. Регулярное тестирование на гонки, использование атомарных операций и идемпотентных ключей — минимальный набор, который должен быть в каждом банковском и high-load проекте. Для пентестера же умение находить и эксплуатировать race condition — один из главных навыков, который выделяет его из толпы сканерозапускателей.
Что такое race condition в вебе
Race condition возникает, когда несколько параллельных запросов обрабатываются в непредсказуемом порядке, и приложение не обеспечивает атомарность критических операций. Простейший пример — два одновременных перевода с одного счёта. Если проверка баланса и списание не изолированы, оба запроса могут увидеть достаточный остаток и выполниться, удвоив списание.
В веб-контексте это не классическая гонка потоков внутри одного процесса, а конкуренция HTTP-запросов к одному ресурсу. Типичная цель — состояние гонки между проверкой (check) и действием (use), известное как TOCTOU (time-of-check to time-of-use).
Почему race condition критичны в 2026 году
- Микросервисная архитектура — распределённые транзакции сложнее изолировать, саги и eventual consistency порождают окна гонок.
- Бессерверные функции — Stateless-природа и автоматическое масштабирование увеличивают конкурентность.
- Высокоскоростные протоколы — HTTP/2 и HTTP/3 позволяют отправлять десятки запросов в рамках одного соединения практически одновременно, делая атаку single-packet реальностью.
Классические сценарии эксплуатации
- Повторное применение промокода. Отправка одного и того же купона в параллельных запросах до того, как первый из них пометит код использованным. Результат — многократная скидка.
- Превышение лимитов. Например, вывод средств сверх баланса или голосование несколько раз с одного аккаунта, если проверка лимита выполняется без блокировки.
- Обход антифрод-проверок. Одновременный перевод средств и отзыв согласия на операцию — классика для банковских приложений, где задержка между скорингом и исполнением может достигать сотен миллисекунд.
- Двойное расходование (double-spend). Актуально не только для криптовалют, но и для внутренних валют игр, бонусных баллов, где баланс — просто число в БД.
- Манипуляции с корзиной. Добавление товара по одной цене и оформление заказа после изменения цены на сервере, если финальная стоимость не перепроверяется атомарно.
В 2026 году арсенал пентестера пополнился специализированными средствами, заточенными именно под конкурентные атаки.
- Burp Suite + Turbo Intruder. Расширение Turbo Intruder позволяет отправлять тысячи запросов с минимальной задержкой, используя один или несколько соединений. Ключевая фича — возможность управлять пайплайнингом и синхронизацией.
- Turbo Intruder Scripts. Кастомные Python-скрипты внутри Turbo Intruder дают тонкий контроль над очередностью и задержками. Пример скрипта для last-byte sync рассмотрим ниже.
- Single-Packet Attack. Техника, использующая мультиплексирование HTTP/2: все запросы упаковываются в один TCP-пакет и отправляются одновременно. Инструменты: h2csmuggler, кастомные реализации на Python с библиотекой h2.
- Race Condition Tester (Burp Extension). Специализированное расширение для автоматизации базовых сценариев: отправка двух-трёх конкурентных запросов и сравнение ответов.
Смысл метода — отправить несколько запросов так, чтобы сервер начал их обработку максимально одновременно. В Turbo Intruder для этого есть встроенная функция gate. Пример базового скрипта:
python
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=1,
engine=Engine.BURP2
)
# Накапливаем запросы
for i in range(20):
engine.queue(target.req, gate='race')
# Отправляем все разом
engine.openGate('race')
def handleResponse(req, interesting):
if 'success' in req.response:
table.add(req)
Этот скрипт помещает 20 запросов в очередь, а затем открывает «ворота», позволяя им отправиться практически одновременно. Для HTTP/1.1 задержка всё равно будет, но для многих приложений достаточно.
Single-Packet Attack: прорыв 2026 года
HTTP/2 и HTTP/3 позволяют мультиплексировать несколько потоков в рамках одного TCP-соединения, а затем передать их в одном сетевом пакете. Это сводит разницу во времени обработки к наносекундам.
Инструменты:
- nmap с --race скриптами (NSE).
- Собственные скрипты на Python с библиотекой hyper или aiohttp с HTTP/2.
- Специализированная утилита racepwn (форк Burp-расширений).
python
import httpx, asyncio
async def send():
async with httpx.AsyncClient(http2=True) as client:
tasks = [client.post('https://bank.example.com/api/transfer',
json={'amount': 100, 'to': 'attacker'})
for _ in range(5)]
await asyncio.gather(*tasks)
asyncio.run(send())
Если сервер не использует атомарные блокировки, все 5 запросов могут уйти в обработку до того, как баланс будет обновлён.
Как находить потенциально уязвимые точки
При пентесте нужно обращать внимание на:
- Эндпоинты с критическими операциями: пополнение баланса, списание, применение промокодов, изменение email/номера телефона, голосование.
- Отсутствие rate limiting на уровне бизнес-логики. Если WAF ограничивает 10 запросов/сек, это не мешает отправить 2-3 конкурентных запроса.
- Неидемпотентные операции. POST-запросы, которые создают ресурс или изменяют состояние.
- Использование очередей без гарантий порядка. Если задача кладётся в очередь и обрабатывается асинхронно, всегда есть окно гонки.
- Признаки в ответах. Разное время ответа при параллельных запросах может указывать на попытку сервера обработать их последовательно, но с задержками.
Разработчикам в 2026 году стоит придерживаться проверенных подходов:
- Атомарные операции в БД. UPDATE ... WHERE balance >= amount вместо SELECT + UPDATE.
- Пессимистичные блокировки. SELECT FOR UPDATE для критических строк на время транзакции.
- Идемпотентность. Использование ключей идемпотентности (idempotency key), которые клиент обязан передавать. Сервер проверяет, не был ли этот ключ уже обработан.
- Распределённые блокировки. Redis (Redlock), Zookeeper для координации между сервисами.
- Ограничение параллельности. На уровне API Gateway ограничить число одновременных запросов от одного пользователя к критическому эндпоинту (например, не более 1-2).
- Тестирование. Обязательное нагрузочное тестирование с конкурентными сценариями, включая single-packet атаки.
- Разведка. Определи все эндпоинты, меняющие состояние (POST/PUT/PATCH). Для каждого отметь, есть ли зависимость от предыдущего состояния (баланс, лимит, доступность).
- Подготовка запроса. В Burp Suite создай таб с запросом. Подготовь 10-20 копий.
- Turbo Intruder. Запусти скрипт last-byte sync. Проанализируй ответы: если больше одного вернули успех там, где ожидался один, — уязвимость.
- Single-Packet. Для критичных случаев повтори атаку с HTTP/2. Используй curl --http2 с параллельным запуском или Python-скрипт.
- Влияние на бизнес-логику. Задокументируй реальный ущерб: сколько денег/баллов/единиц товара можно украсть. Это повысит критичность.
- Обход ограничений. Если есть капча или CSRF-токен, попробуй переиспользовать один токен в нескольких запросах (часто CSRF-токены валидны в течение короткого промежутка).
- Race condition как сервис: мошенники автоматизируют атаки через бот-фермы, синхронизируя запросы по NTP.
- Защита на уровне API-шлюзов: встроенные детекторы гонок, анализирующие временные метки запросов.
- Учёт в пентест-методологиях: PTES и OWASP WSTG дополнены чек-листами для конкурентных атак.
Race condition — это не «баг», а архитектурный просчёт. В 2026 году, когда системы стали ещё более распределёнными, а злоумышленники вооружены single-packet атаками, игнорировать эту поверхность атаки нельзя. Регулярное тестирование на гонки, использование атомарных операций и идемпотентных ключей — минимальный набор, который должен быть в каждом банковском и high-load проекте. Для пентестера же умение находить и эксплуатировать race condition — один из главных навыков, который выделяет его из толпы сканерозапускателей.