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

API Mass Assignment: Повышение привилегий через PATCH

Уязвимость Mass Assignment возникает, когда приложение слепо доверяет входному JSON и биндит его напрямую в модель базы данных.

mediumgolangPro
Задача
# Mass Assignment в REST API: повышение привилегий через JSON ## Сценарий Вы аудируете REST API интернет-магазина **SecureShop**. У приложения есть JSON API для редактирования профиля: пользователь видит свои данные через `GET /api/user`, редактирует их через `PUT /api/user`. UI-форма позволяет изменить имя и аватар, но сам API возвращает **больше полей**, чем форма редактирует. Команда уверена, что эндпоинт безопасен — пользователь работает только со своим профилем, а данные подставляются с серверной стороны. По данным внутреннего аудита, доступ к admin-функциональности приложения требует роль администратора, а флаг возвращается в ответе API сразу после получения этой роли. ## Цель 1. Изучите ответ `GET /api/user` — какие поля сервер возвращает, помимо тех, что отображаются в UI. 2. Найдите способ модифицировать поле, которое сервер возвращает но UI не редактирует — через прямой запрос к JSON API. 3. Получите admin-функциональность и извлеките флаг из ответа. ## Теория Mass Assignment в REST API — частный случай той же уязвимости, что встречается в form-handlers (см. `golang-go-idor-mass-assignment`), но применённый к структурированному JSON API. Уязвимость возникает когда обработчик API принимает JSON-тело и применяет **все** переданные поля к доменной модели или к SQL UPDATE без явного allowlist. В JSON-API уязвимость особенно частая, потому что: 1. Структура данных модели **видна** через `GET /api/...`-эндпоинт того же ресурса — атакующему не нужно гадать имена полей. 2. Многие фреймворки (`encoding/json`, Fiber `BodyParser`, Echo `Bind`) поощряют «удобный» паттерн bind в полную модель. 3. Внешние клиенты ожидают «гибкости» от API — разработчики оставляют open schema. **Уязвимый паттерн:** ```go // Тело декодируется в generic map или в саму доменную модель, // все поля применяются к UPDATE без allowlist var updates map[string]interface{} json.NewDecoder(r.Body).Decode(&updates) for field, value := range updates { db.Exec("UPDATE users SET "+field+"=? WHERE id=?", value, user.ID) } ``` Атака — простейшая: отправить `PUT /api/user` с дополнительным полем привилегий (`role`, `is_admin`, `permissions`, `verified`), которое известно атакующему из ответа `GET /api/user`. Сервер прозрачно его применяет, потому что не делает различия между «полями для самообслуживания» и «server-managed полями». ## Точка входа атаки | Параметр | Значение | |----------|----------| | Учётные данные | `demo` / `demo` | | Эндпоинт чтения профиля | `GET /api/user` | | Эндпоинт редактирования | `PUT /api/user` (JSON body) | | Цель | повысить роль текущего пользователя через JSON API и получить флаг из ответа |
🚧 Сайт в разработке. Полный функционал пока недоступен. Все вопросы — support@hackandfix.ru