AuthZ и «чужой id»: что сканер не поймает
SAST и «AI security review» хорошо ищут секреты и известные CVE.
А вот «пользователь A открыл заказ пользователя B, подставив id=1247 в URL» — почти всегда ручная проверка.
ИИ при генерации CRUD часто делает ровно это: login есть, проверки владельца записи — нет.
Цепочка материалов: риски ИИ-кода → чеклист 15 мин → этот текст.
Authentication ≠ Authorization
| Authentication (AuthN) | Authorization (AuthZ) | |
|---|---|---|
| Вопрос | Кто ты? | Можешь ли ты это сделать? |
| Пример | Логин по паролю / OAuth | Это твой заказ или чужой? |
| ИИ часто | ✅ делает | ❌ забывает |
IDOR — «Insecure Direct Object Reference»
Классика:
GET /api/orders/1247
GET /api/users/42/profile
GET /download/invoice/8831.pdf
Если сервер отдаёт данные только потому, что id существует — без проверки «этот id принадлежит текущему user_id» — это дыра.
На пентестах это OWASP Top 10, в pet-проектах — «мы же MVP».
Горизонтальная эскалация
Два обычных пользователя одного уровня. A не должен видеть данные B.
Вертикальная эскалация
Обычный пользователь получает права админа:
POST /api/users/meс полем"role": "admin"в теле;- скрытые эндпоинты
/admin/...без middleware; - GraphQL mutation «обнови профиль» с полем
isAdmin.
API и мобильные клиенты
«Фронт не показывает кнопку» — не защита. Любой вызовет curl.
# два токена разных пользователей
curl -H "Authorization: Bearer $TOKEN_USER_B" \
https://api.example.com/v1/invoices/INVOICE_OF_USER_A
Ответ 200 с телом — баг. 404 «не найдено» для чужого id — приемлемый паттерн (не раскрывать факт существования).
Почему сканер это не ловит
- правило «доступ» завязано на бизнес-логику, не на синтаксис;
- нужны два аккаунта и сценарий «создал → попробовал украсть»;
- ИИ-code review без контекста домена часто пишет «выглядит нормально».
Snyk, Semgrep, gitleaks — полезны для другого слоя. AuthZ — ваш мозг и чеклист.
Ручной чеклист (5 минут на фичу)
- У каждого объекта с PII/деньгами есть
owner_id/ tenant? - Каждый read/update/delete проверяет владельца на сервере?
- Списки (
GET /orders) фильтруются по текущему user, не «все из БД»? - Файлы по прямой ссылке — с подписью или проверкой сессии?
- Админские действия — отдельный guard, не «if (user)»?
Когда дыра уже в проде
AuthZ-баг часто всплывает как «странный тикет в поддержку», не как алерт CVE. Имеет смысл мониторить доступность и 5xx — чтобы отличить «утечку данных» от «сайт лёг». Серверный baseline — аудит VPS; продуктовый — этот текст + чеклист перед продом.
Инфраструктура после релиза
Код проверил — дальше следи за 502, SSL и диском. Mediops: алерты в Telegram или MAX.