Business Logic: Стек купонов
Система купонов позволяет применять несколько купонов одновременно, суммируя скидки сверх допустимого
mediumgolangPro
Задача
# Coupon Stacking: накопление скидок без ограничения суммы
## Сценарий
Вы зарегистрированный пользователь интернет-магазина **SecureShop** с балансом **$500**. В магазине доступна система купонов: на странице корзины можно ввести промо-код и получить скидку. Команда уверена, что система купонов корректна — каждый купон даёт фиксированный процент. По данным внутреннего аудита, в каталоге есть товар **CTF Flag** стоимостью **$9999**, к которому привязан флаг — обычной покупкой он недоступен с балансом $500. Требуется получить этот товар легитимными для системы запросами.
## Цель
1. Изучите механизм применения купонов: что именно проверяет сервер при `POST /cart/coupon` — существование купона, его принадлежность пользователю, уже применённые купоны в корзине.
2. Найдите способ снизить итоговую стоимость заказа до суммы, доступной с баланса $500, **только через применение купонов** (без подмены цены, количества или ID товара).
3. Оформите заказ на товар **CTF Flag** и извлеките флаг из подтверждения заказа.
## Теория
Уязвимости класса **Business Logic** — нарушение бизнес-инвариантов, не покрытых классическими защитами (auth/CSRF/SQLi). Купонная система имеет естественные инварианты: «один купон в корзине», «купон одноразовый на пользователя», «итоговая скидка ≤ 100%». Если разработчик не выразил эти инварианты в коде, привычная защита не спасёт — сервер примет каждый запрос как валидный.
**Уязвимый паттерн:**
```go
// Применение купона без проверки уже применённых — каждое применение добавляет скидку
INSERT INTO cart_coupons (user_id, coupon_id) VALUES (?, ?)
// Расчёт итоговой скидки — сумма по всем активным купонам корзины
SELECT SUM(discount) FROM cart_coupons JOIN coupons ON ... WHERE user_id=?
```
При повторном применении одного и того же купона вставка проходит без конфликта (нет UNIQUE-ограничения, нет проверки в коде), а скидки суммируются — суммарный процент превышает 100%, и итоговая цена опускается до нуля. CWE-840 (Business Logic Errors), OWASP API4:2023 «Unrestricted Resource Consumption» в части business invariants.
## Точка входа атаки
| Параметр | Значение |
|----------|----------|
| Учётные данные | `demo` / `demo` (баланс $500) |
| Эндпоинт применения купона | `POST /cart/coupon` (поле `code`) |
| Эндпоинт оформления | `POST /cart/checkout` |
| Доступные купоны | `SAVE10` (10%), `HACK20` (20%) |
| Цель | оформить заказ на товар **CTF Flag** ($9999) и извлечь флаг из подтверждения |