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

CSRF: Несанкционированное действие через поддельный запрос

Форма администратора не защищена CSRF-токеном. Заставь бота выполнить действие от имени admin.

easygolangPro
Задача
# CSRF: Несанкционированное действие от имени администратора ## Сценарий Вы проводите аудит безопасности интернет-магазина **SecureShop**. В админ-панели обнаружен эндпоинт активации распродажи `POST /admin/activate-sale` — он добавляет в каталог промо-товар и доступен только пользователям с ролью `admin`. Однако обработчик проверяет лишь наличие admin-сессии и **не проверяет**, откуда пришёл запрос. У приложения есть бот-администратор, который проверяет жалобы через форму **«Report to Admin»** — он откроет любую переданную HTML-страницу с уже активной admin-сессией. ## Цель 1. Найдите эндпоинт, выполняющий чувствительное действие, и убедитесь, что он не защищён CSRF-токеном. 2. Подготовьте HTML-страницу с автоматически отправляемой POST-формой, нацеленной на этот эндпоинт. 3. Через форму `/report` доставьте ссылку на эту страницу боту-администратору. 4. Убедитесь, что бот, открыв страницу, неявно выполнил `POST /admin/activate-sale` со своими admin-куками. 5. Получите флаг — после успешной атаки в каталоге появится товар «CTF Flag», в описании которого указано значение флага. ## Теория **CSRF (Cross-Site Request Forgery)** — атака, при которой злоумышленник заставляет браузер жертвы выполнить запрос на целевой сайт от её имени. Браузер автоматически прикрепляет cookies к любому запросу на нужный домен, поэтому залогиненная сессия жертвы передаётся вместе с запросом, инициированным внешней страницей атакующего. Если сервер не отличает «свои» формы от «чужих», действие выполняется с правами жертвы. Стандартная защита — **CSRF-токен**: уникальное значение, привязанное к сессии и встраиваемое в каждую форму. Внешний сайт не может прочитать значение cookie или сессионного токена жертвы (Same-Origin Policy), а значит и не может подставить корректный CSRF-токен в свою форму. Сервер, не найдя токена или увидев несовпадение, отвергает запрос. **Уязвимый паттерн:** ```go // Обработчик чувствительного действия проверяет только сессию, // но не источник запроса: func (h *Handler) ActivateSale(w http.ResponseWriter, r *http.Request) { user := h.getUser(r) if user == nil || user.Role != "admin" { http.Error(w, "Access Denied", 403) return } // CSRF-токена нет — любой сайт может вызвать этот эндпоинт flag := env.GetFlag() h.db.Exec(`INSERT OR IGNORE INTO products ...`, flag) http.Redirect(w, r, "/admin", 302) } ``` ## Точка входа атаки | Параметр | Значение | |----------|----------| | Ваш аккаунт | `demo` / `demo` | | Уязвимый эндпоинт | `POST /admin/activate-sale` | | Доставка боту | `POST /report` (бот откроет переданный URL) | | Exploit Server / hosting | внешний хостинг для HTML-payload (см. панель лабы → вкладка HTML Payload) | | Где появится флаг | `GET /catalog` — товар «CTF Flag» |
🚧 Сайт в разработке. Полный функционал пока недоступен. Все вопросы — support@hackandfix.ru