Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Состояние гонки иногда позволяет вмешаться в алгоритмы обработки данных: от оплаты корзины в интернет‑магазине до механики перевыпуска API-ключей с повышением привилегий. На примерах с HTTP/2 и single-packet attack я покажу, как правильно подобранный момент атаки дает возможность «вырваться вперед на повороте» и буквально переписать бизнес‑логику приложения.
Это исследование получило первое место на Pentest Award 2025 в категории «Hack the logic». Соревнование ежегодно проводится компанией Awillix.
warning
Статья имеет ознакомительный характер и предназначена для специалистов по безопасности, проводящих тестирование в рамках контракта. Автор и редакция не несут ответственности за любой вред, причиненный с применением изложенной информации. Распространение вредоносных программ, нарушение работы систем и нарушение тайны переписки преследуются по закону.
Race Condition (состояние гонки) — это уязвимость в веб‑приложениях, которую относят к группе уязвимостей бизнес‑логики. Если ты аппсек, багхантер или пентестер, то тебе будет полезно в этом механизме разобраться.
Как эта уязвимость выглядит в реальных веб‑приложениях? В голову сразу приходит такой сценарий: у меня есть десять рублей, и товар стоит десять рублей, можно одновременно отправить два запроса на его оплату, чтобы веб‑приложение одновременно поработало с 10-рублевым балансом, и если оба пройдут, то получится два товара за десять рублей, итого — один бесплатный товар. Или, например, такое: в кино остался последний билет, а нас двое, можно отправить два запроса на покупку билета одновременно, и если все пройдет как надо, то в ответе будет два билета. По крайней мере такие сценарии и еще пару похожих мне предложил DeepSeek R1.
Такие сценарии работают за счет эксплуатации одной конечной точки (одного запроса), которая неправильно работает с нужными переменными — балансом кошелька или количеством непроданных билетов. Один обработчик запроса параллельно достает баланс или количество билетов из базы данных для двух запросов и видит, что для обоих запросов ему возвращается десять рублей или один последний билет, после чего он радостно идет выдавать покупку, так как денег хватает или билет остался. Профит!
С помощью такой уязвимости мы как бы перескакиваем барьер нулевого баланса и уводим переменную в отрицательные значения (в некоторых случаях наоборот — увеличиваем количество и перескакиваем верхнюю границу).
А что, если я скажу: это лишь вершина айсберга и меньшая часть потенциала уязвимости?
Мы привыкли использовать Race Condition, чтобы перепрыгнуть граничное состояние, где какая‑то переменная равна нулю, но, если действовать оперативно, можно перепрыгнуть целый кусок логики. Давай в качестве первого примера разберем простой и понятный сценарий, он поможет понять суть.
Наш первый заезд будет на трассе с оплатой корзины. Вот как происходит оплата.
Вроде все хорошо, но давай посмотрим на процесс с другой стороны. Мы здесь можем повлиять только на первый и второй шаги, а именно изменение состояния корзины и отправку корзины на оплату. Будем считать, что с оплатой на четвертом шаге все окей, так как это сторонний сервис.
Но что, если в нашей гонке мы запустим одновременно добавление товара в корзину и ее оплату? Сможем ли мы между вторым и третьим шагом добавить свой товар так, чтобы состояние корзины изменилось за «мгновение» до отправки запроса в эквайринг? Сможет ли веб‑сайт успеть добавить в корзину товар и одновременно сделать так, чтобы в сумму, которую он передаст интернет‑эквайрингу, вошла стоимость этого товара?
Источник: xakep.ru