Перейти к содержимому
← Каталог golang Race Condition

Race Condition: Double-spend баланса

Race condition: чтение и списание баланса без транзакции позволяет двойную трату при параллельных запросах.

mediumgolangPro
Задача
# Race Condition: TOCTOU в операциях с балансом (double spend) ## Сценарий Вы — аудитор интернет-магазина **SecureShop**. У каждого зарегистрированного пользователя есть баланс, с которого списываются средства при покупке товаров. Команда уверена, что эндпоинт покупки безопасен — серверный код проверяет баланс перед списанием, и пользователь не может потратить больше, чем у него есть. По данным внутреннего аудита, в каталоге магазина есть служебный товар «CTF Flag» — он не должен быть приобретён обычным пользователем, потому что баланс жертвы заведомо меньше его цены. ## Цель 1. Исследуйте серверную логику обработчика покупки — как именно сервер проверяет достаточность средств и списывает их. 2. Найдите способ обойти проверку баланса, не прибегая к классическим уязвимостям (без SQL-инъекций, без подмены параметров запроса) — используя свойства параллельной обработки запросов сервером. 3. Приобретите служебный товар «CTF Flag» и получите флаг из ответа. ## Теория TOCTOU (Time-of-Check Time-of-Use) — класс уязвимостей, при которых между моментом проверки условия и моментом фактического использования его результата существует временное окно, в которое состояние может измениться. В контексте веб-приложений это часто выглядит как последовательность «прочитать → проверить → записать», выполняемая на уровне приложения **без атомарной транзакции** и **без блокировки строки** в БД. **Уязвимый паттерн:** ```go // Read-Check-Update без транзакции — race condition balance := readBalance(userID) // 1. read if balance >= price { // 2. check updateBalance(userID, balance-price) // 3. update — между шагами могут пройти другие запросы insertOrder(userID, productID) } ``` При параллельной отправке нескольких запросов на покупку сервер обрабатывает их в нескольких goroutine одновременно. Если все они успевают выполнить шаг 1 **до того**, как любой из них завершит шаг 3, все увидят одинаковый баланс, все пройдут проверку (шаг 2), и все произведут списание. Итог: за один реальный баланс пользователь получает несколько товаров — баланс уходит в минус, заказы дублируются. ## Точка входа атаки | Параметр | Значение | |----------|----------| | Учётные данные | `demo` / `demo` | | Эндпоинт покупки | `POST /api/buy` (параметр `product_id`) | | Эндпоинт проверки баланса | `GET /api/balance` | | Цель | приобрести «CTF Flag» через параллельные запросы и получить флаг из ответа |
🚧 Сайт в разработке. Полный функционал пока недоступен. Все вопросы — support@hackandfix.ru