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.

Тест: залогинься двумя тестовыми аккаунтами. Создай заказ/документ от user1. От user2 запроси тот же URL с id объекта user1. Ожидание: 403 или пустой ответ, не JSON с чужими полями.

Вертикальная эскалация

Обычный пользователь получает права админа:

  • 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 минут на фичу)

  1. У каждого объекта с PII/деньгами есть owner_id / tenant?
  2. Каждый read/update/delete проверяет владельца на сервере?
  3. Списки (GET /orders) фильтруются по текущему user, не «все из БД»?
  4. Файлы по прямой ссылке — с подписью или проверкой сессии?
  5. Админские действия — отдельный guard, не «if (user)»?

Когда дыра уже в проде

AuthZ-баг часто всплывает как «странный тикет в поддержку», не как алерт CVE. Имеет смысл мониторить доступность и 5xx — чтобы отличить «утечку данных» от «сайт лёг». Серверный baseline — аудит VPS; продуктовый — этот текст + чеклист перед продом.

Инфраструктура после релиза

Код проверил — дальше следи за 502, SSL и диском. Mediops: алерты в Telegram или MAX.