Репост из «Хакер | Этичный хакинг с Михаилом Тарасовым»

⚡ Как я стал админом одним POST-запросом: Register Admin Challenge в OWASP Juice Shop



Гоняю по вечерам OWASP Juice Shop - магазинчик, специально напичканный дырами для тренировки. Взялся за челлендж «Register Admin» - зарегистрировать юзера с правами администратора.

Точка входа 🔍
Регистрация идёт через авто-сгенерённый CRUD - POST /api/Users. Рука сама тянется подкинуть лишнее поле в JSON:
JSON

{ "email": "x@y.z", "password": "123", "role": "admin" }

Сервер честно кладёт всё тело запроса в модель. Вайтлиста нет. Клиент попросил роль - клиент получил роль. Классика mass assignment: доверять инпуту от юзера - как оставлять шелл с root на проде.

Бам - админка за один запрос. 💥

Бонус-раунд: выбери правильный фикс 🎯
К задачке есть задачка посложнее - найти строку с багом и выбрать, как её починить. Виноват хук resource.create.send.before(...): последнее место, где можно перетереть роль до сохранения, - пропущено.

Фиксы:

❌ Добавить 'role' в exclude - обманка. В finale это работает на сериализацию ответа, а не на запись. Баг живее всех живых.
✅ Форсить роль на сервере: context.instance.role = 'customer' - критичные поля выставляет только бэк. Правильный фикс.
❌ «Если роль пришла - оставь как есть» - это не фикс, это официальное сохранение уязвимости 🍬
❌ Удалить несвязанный код - remediation by deletion, мимо кассы.

Выводы 💻

Увидел авто-CRUD (finale, loopback) - шли всё, что модель не должна принимать: role, isAdmin, balance.
«Не возвращается в ответе» ≠ «нельзя записать».
Исправление одно: критичные поля задаёт только сервер. Период.

Админы, которые думают, что их код безопасен, - мой любимый вид дичи 🦌
Просмотры: 13
Открыть в MAX Сообщить о неточности

Сообщить о неточности

Опишите, что нужно исправить. Если есть источник, добавьте ссылку.

Вы покидаете datool.ru

Ссылка ведёт на внешний сайт. datool.ru не отвечает за его содержимое — проверьте адрес, прежде чем вводить пароли или платёжные данные.

Переход через 10 с

Перейти