Перейти к содержимому

Поиск по платформе

Promo Code Race

Состояние гонки при активации промокодов.

Автор: Hack & Fix
Освоишь: SELECT FOR UPDATEadvisory-lockidempotency key
Средне+60 XP ~45 мин golang
CWE-362 · A04:2021 Pro
Обложка: Promo Code Race Обложка: Promo Code Race
Задача
# Состояние гонки при применении промокода (TOCTOU) ## Сценарий Вы — специалист по безопасности, приглашённый аудитировать **BitBazaar**, магазин гаджетов с бонусными промокодами. Поводом стала рассылка одноразовых кодов по итогам конференции: финансовая сверка показала, что начислений на балансы оказалось заметно больше, чем самих кодов. Разработка настаивает, что повторное применение исключено — «проверка на повторное использование есть в коде». Вам поручили проверить этот узел и оценить максимальный ущерб: закрытый товар **CTF Flag** в каталоге стоит $2000, а на тестовом счёте — нулевой баланс. ## Цель 1. Изучите серверную логику применения купона: где выполняется проверка «этот пользователь уже использовал этот код?» и где фиксируется факт использования. 2. Добейтесь многократного начисления бонуса одним и тем же кодом в рамках одной учётной записи — без подмены данных запроса и без повторной регистрации. 3. Накопите сумму, достаточную для покупки товара **CTF Flag**, и оформите заказ — флаг появится в вашем профиле. ## Теория TOCTOU (time-of-check to time-of-use) — уязвимость, при которой между проверкой условия и использованием её результата существует временное окно, и в это окно состояние успевает измениться. Применение одноразового купона — хрестоматийный случай: сначала отдельным запросом читается, был ли код уже использован, и только потом записывается факт использования и начисляется бонус. Между этими шагами сервер выполняет медленную операцию — эмуляцию обращения к платёжному сервису, — которая специально растягивает окно. **Уязвимый паттерн:** ```go // Проверка и запись — два независимых шага: db.QueryRow("SELECT count(*) FROM used_coupons WHERE user_id=? AND code=?", uid, code).Scan(&count) if count == 0 { // ...позже — запись факта использования и начисление бонуса } ``` При параллельной отправке одинаковых запросов несколько обработчиков успевают пройти проверку до того, как любой из них завершит запись. Каждый видит «код ещё не использован» — и каждый начисляет бонус. Атака при этом полностью имитирует поведение обычного пользователя: те же поля, тот же код, меняется лишь количество одновременных запросов. ## Точка входа атаки `POST /cart/coupon` — форма применения купона на странице корзины; поля передаются как обычная форма: * `code` — промокод, например `GIFT100` (существует в системе и начисляет $100) * `csrf_token` — скрытое поле, которое заполнено во всех формах сайта после входа Состояние наблюдайте в корзине и профиле: `GET /cart`, `GET /profile`. * **Обычный пользователь:** `demo` / `demo` * **Администратор:** `admin` / `???`

Похожие лабораторные (4)

другие лабы по этой уязвимости
Обложка лабы: Race Condition: Double-spend баланса Обложка лабы: Race Condition: Double-spend баланса
Race

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

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

+60 XP
Go Pro
Exploit Fix
Обложка лабы: Promo Code Race Обложка лабы: Promo Code Race
Race

Promo Code Race

Состояние гонки при активации промокодов (PHP).

+60 XP
PHP Pro
Exploit Fix
Обложка лабы: Promo Code Race Обложка лабы: Promo Code Race
Race

Promo Code Race

Состояние гонки при активации промокодов (Python).

+60 XP
Python Pro
Exploit Fix
Обложка лабы: Race Condition: Гонка при активации промокода в Express Обложка лабы: Race Condition: Гонка при активации промокода в Express
Race

Race Condition: Гонка при активации промокода в Express

Эндпоинт активации промокода в Express + better-sqlite3 содержит TOCTOU между проверкой счётчика и обновлением баланса. Получи бонус несколько раз параллельными запросами, накопи баланс и открой VIP-функцию с флагом.

+90 XP
Node.js Pro
Exploit Fix