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

Business Logic: Подмена цены в форме

Checkout читает цену товара из скрытого поля формы вместо базы данных, позволяя подменить стоимость заказа

mediumgolangPro
Задача
# Price Manipulation: доверие клиентским финансовым данным ## Сценарий Вы зарегистрированный пользователь интернет-магазина **SecureShop** с балансом **$500**. В каталоге есть товар **CTF Flag** стоимостью **$9999** — обычной покупкой он недоступен. Команда уверена, что процесс оформления заказа защищён — есть авторизация, CSRF-токен, проверка достаточности баланса. По данным внутреннего аудита, существует способ оформить заказ на CTF Flag, не повышая баланс и не подделывая ID товара, а используя саму процедуру `checkout` так, как её обрабатывает сервер. ## Цель 1. Изучите процесс оформления заказа: какие именно поля формы отправляются на `POST /cart/checkout`, какие из них сервер использует для расчёта итоговой стоимости и списания с баланса. 2. Найдите параметр, которому сервер доверяет как финансовому решению, и определите, почему этому параметру нельзя доверять с точки зрения архитектуры. 3. Используйте обнаруженный вектор для оформления заказа на CTF Flag в пределах баланса $500 и извлеките флаг из подтверждения заказа. ## Теория Уязвимости класса **Business Logic / Client-Side Trust** возникают, когда сервер использует финансовые данные, пришедшие от клиента, как источник истины. Классический случай — скрытое поле формы `total_price`, которое сервер списывает с баланса напрямую, вместо того чтобы пересчитать стоимость из БД на основе содержимого корзины. С точки зрения SQL-инъекций и XSS обработчик может быть полностью корректен, но любой HTTP-клиент (браузерный DevTools, Burp, curl) может изменить значение скрытого поля перед отправкой. CWE-602 «Client-Side Enforcement of Server-Side Security», OWASP A04:2021 «Insecure Design». **Уязвимый паттерн:** ```go // Сервер списывает сумму, которую прислал клиент total, _ := strconv.Atoi(r.FormValue("total_price")) db.Exec("UPDATE users SET balance = balance - ? WHERE id = ?", total, user.ID) ``` Скрытое поле формы (`<input type="hidden" name="total_price" value="...">`) — это UX-удобство, чтобы шаблон отдал серверу уже рассчитанную сумму без повторного запроса к БД. Но в HTTP нет способа гарантировать, что значение из формы пришло именно из вашего шаблона: атакующий просто меняет `value` через DevTools/Burp/curl и заказ оформляется по подменённой цене. Бизнес-инвариант «итоговая стоимость = сумма цен в корзине из БД» должен быть выражен в коде сервера, а не в шаблоне. ## Точка входа атаки | Параметр | Значение | |----------|----------| | Учётные данные | `demo` / `demo` (баланс $500) | | Эндпоинт оформления | `POST /cart/checkout` | | Цель | оформить заказ на товар **CTF Flag** ($9999) в пределах баланса $500 и извлечь флаг из подтверждения |
🚧 Сайт в разработке. Полный функционал пока недоступен. Все вопросы — support@hackandfix.ru