Админка по ?isAdmin=true
«Админка готова, доступ только у админов»:
app.get('/admin/users', async (req, res) => {
if (req.query.isAdmin === 'true') {
return res.json(await getAllUsers());
}
return res.status(403).json({ error: 'Forbidden' });
});
На стенде с ?isAdmin=true в ссылке из фронта всё работает. Джун делает вывод: «каждый админ имеет доступ».
Уязвимость — Broken Access Control (OWASP Top 10, #1): права решаются данными с клиента, а не ролью в сессии, JWT или записью в БД на сервере. Любой пользователь (и аноним, если маршрут открыт) может подставить тот же параметр.
RBAC и различие AuthN / AuthZ — аутентификация и авторизация. Каталог IDOR и API-угроз — 8.07 / 128.
Эксплуатация за пять секунд
GET /admin/users?isAdmin=true HTTP/1.1
Host: api.example.com
В браузере:
https://api.example.com/admin/users?isAdmin=true
Ответ — полный список пользователей из getAllUsers(): email, id, внутренние поля. Без логина, если эндпоинт не закрыт middleware auth.
В curl:
curl -s "https://api.example.com/admin/users?isAdmin=true"
Сервер честно отдаёт 403 без параметра — это создаёт иллюзию защиты. Проверка «есть ли флаг админа» и проверка «кто этот админ по данным сервера» — разные задачи. Здесь реализована только первая, и флаг контролирует клиент.
Откуда берётся ошибка
Частые варианты той же логики:
| «Проверка» на сервере | Что подставляет атакующий |
|---|---|
req.query.isAdmin === 'true' | ?isAdmin=true |
req.body.role === 'admin' | {"role":"admin"} в JSON |
req.cookies.admin === '1' | Cookie admin=1 в DevTools |
req.headers['x-admin'] | X-Admin: true |
Фронт: if (user.isAdmin) fetch(...) | Прямой вызов API без фронта |
Фронтенд может прятать кнопку «Админка». API обязан проверять права сам — по серверному контексту после auth.
Как должно быть
- Аутентификация — middleware
auth: естьreq.user/req.userId. - Авторизация — роль из подписанного источника (JWT claim
roles, поле в сессии после login, lookup в БД), не из query.
app.get('/admin/users', auth, requireRole('admin'), async (req, res) => {
return res.json(await getAllUsers());
});
function requireRole(role) {
return (req, res, next) => {
const roles = req.user.roles ?? [];
if (!roles.includes(role)) {
return res.status(403).json({ error: 'Forbidden' });
}
next();
};
}
Для JWT — claim realm_access.roles / groups после проверки подписи (см. JWT — семь строк). Для сессии — роль записана на сервере при входе, клиент её не присылает заново.
Тест: обычный пользователь с валидным токеном вызывает /admin/users без query — только 403. Подстановка ?isAdmin=true ничего не меняет.
Родственные промахи
- IDOR —
GET /users/123отдаёт чужой профиль, если не проверятьowner_id === req.user.id. Тот же класс: «есть токен» ≠ «можно этот объект». - Mass assignment —
PATCH /profileс{"isAdmin":true}обновляет роль, если сервер не фильтрует поля. - Путь только на фронте —
/adminв React Router без guard на API.
Все они лечатся единой политикой на сервере для каждого эндпоинта.
Чек-лист
- Ни один query, body, cookie или header не выступает источником прав.
- Админские маршруты за
auth+ проверка роли / permission. - Роль в JWT подписана IdP; подделка payload без ключа невозможна.
- Интеграционные тесты: user и admin, без подстановки «секретных» параметров.
- Сканер/Burp по чек-листу OWASP API — каталог угроз.
Связанные материалы
| Тема | Статья |
|---|---|
| RBAC, ABAC | Аутентификация и авторизация |
| IDOR и Broken Access Control | 8.07 / 128 |
| Подделка роли в JWT | JWT — семь строк |
| Mass assignment | 8.07 / 128 — каталог |
См. также
Другие статьи этого же раздела в боковом меню (как на странице "О разделе"). Основы информационной безопасности - роль политик, контроль доступа и базовые принципы защиты данных в корпоративных системах. Аутентификация и авторизация - уровни проверки личности, двухфакторная защита и разграничение прав доступа в информационных системах. Антивирусная защита и лечение заражений - как распознать компрометацию системы, локализовать угрозу и восстановить рабочее состояние. Риски открытых Wi-Fi сетей - как работают passive/active-сканирование и почему публичные точки доступа требуют дополнительных мер защиты. Надёжность паролей — хеширование, соль, менеджеры паролей и типы атак: перебор, словарь, credential stuffing, фишинг, MITM. Фаерволы и сетевые пакеты - как межсетевой экран анализирует трафик и применяет правила фильтрации для защиты инфраструктуры. SSH — это протокол безопасного удалённого доступа к компьютерным системам. DoS и DDoS — как перегружают сервер, ботнет и SYN-flood, уровни атаки L3–L7 и базовая защита. Опасная конфигурация jwt.verify в Node.js — alg none, подмена алгоритма RS256 на HS256, секрет из process.env на уровне модуля и безопасная проверка токена. Эндпоинт change-password без проверки текущего пароля — захват аккаунта при украденной сессии, CSRF и чек-лист безопасной смены пароля. Краткие итоги раздела "Основы информационной безопасности". Чек-лист раздела Основы информационной безопасности — вопросы для самопроверки в энциклопедии Вселенная IT.Основы информационной безопасности
Аутентификация и авторизация
Антивирусная защита и лечение заражённых систем
Риски открытых Wi-Fi сетей
Устройство и надёжность паролей
Фаерволы
Шифрование данных и протокол SSH
DDoS и отказ в обслуживании
JWT — семь строк, которые обходят авторизацию
Смена пароля — пропущенный шаг re-auth
Итоги
Чек-лист самопроверки