Блог о тестировании ·

Аутентификация и авторизация: как тестировщику проверять права доступа

Многие серьёзные security-баги начинаются с простой путаницы: система знает, кто ты, но забывает проверить, принадлежит ли тебе конкретный объект.

Модель проверки доступа
  1. Нет токена: ожидаем 401
  2. Неверный токен: ожидаем 401
  3. Правильный пользователь, не та роль: 403 или нет действия
  4. Правильная роль, чужой объект: 403 или 404

Аутентификация отвечает “кто ты?”

Аутентификация — это вход, пароль, токен, сессия и срок действия. Она подтверждает личность, но не решает, какие данные пользователь может читать или менять.

Базовые проверки: правильные данные, неверный пароль, регистр email, отсутствие токена, истёкший токен и logout.

Авторизация отвечает “что тебе можно?”

Авторизация проверяет роль и владение объектом. Пользователь может быть залогинен и всё равно не иметь права открыть чужой заказ, счёт, документ или карточку клиента.

Здесь часто ломается API: id легко угадать, а скрытая кнопка на фронтенде не защищает backend.

Проверка владения объектом

Создай или найди двух пользователей. Открой объект владельцем, запомни id, затем запроси тот же id токеном второго пользователя. Обычно ожидается 403 или 404.

Почему иногда лучше 404

Для приватных объектов 404 скрывает сам факт существования. 403 говорит, что объект есть, но тебе нельзя. Как правильно — решают требования продукта.

Проверка ролей

Роли нужно проверять и в UI, и в API. Если admin-only кнопка скрыта, всё равно отправь запрос с токеном обычного пользователя.

Скрытая кнопка — это удобство. Отклонённый запрос — это безопасность.

Типичные access-баги

Частые дефекты: нет фильтра по владельцу, роль проверяется только на фронтенде, токен работает после logout, endpoint по-разному отвечает на существующий и несуществующий приватный объект.

В багрепорте про доступ укажи оба аккаунта, контекст токенов и id объекта. Без этого разработчик не воспроизведёт границу прав.

Матрица actor × action × object

Список ролей недостаточен. Построй строки из субъекта, действия и ресурса: manager A читает своего клиента, manager A меняет клиента B, обычный user вызывает admin endpoint, бывший сотрудник использует старый token. Для каждого сочетания нужен expected: allow, deny или скрыть существование.

Проверяй не только GET. BOLA часто закрыта на чтение, но остаётся в PATCH, DELETE, bulk endpoint, export или вложенном object id в JSON. UUID усложняет угадывание, но не заменяет серверную проверку права.

Минимальная access-матрица
Actor       Action  Object        Expected\nmanager A   GET     client A      200\nmanager A   GET     client B      403/404 по контракту\nmanager A   PATCH   client B      403/404, данные не меняются\nviewer      DELETE  client A      403\nno token    GET     client A      401 + WWW-Authenticate

Жизненный цикл сессии и токена

Проверь выдачу, rotation после login или повышения прав, expiry, refresh, logout, отзыв, смену пароля и параллельные устройства. Старый access token иногда живёт до короткого expiry по принятой архитектуре; тогда logout обязан отозвать refresh token и UI не должен обещать больше, чем гарантирует сервер.

  • Session id не остаётся тем же до и после login — иначе возможна session fixation.
  • Cookie имеет Secure, HttpOnly и подходящий SameSite; token не попадает в URL и логи.
  • Истёкший, испорченный и подписанный не тем ключом token отклоняются.
  • После смены роли permission обновляется в согласованный срок, а кэш не оставляет старое право.
  • Refresh reuse, logout и смена пароля ведут себя по документированной политике.

BOLA, BFLA и доступ к отдельным полям

BOLA — пользователь имеет доступ к функции, но backend не проверяет право на конкретный object id. BFLA — пользователь вызывает функцию не своей роли, например обычный manager открывает admin export. Broken Object Property Level Authorization проявляется, когда разрешённый endpoint принимает или возвращает поля, которые этой роли недоступны.

Для CRM это три разные проверки: запросить чужого клиента, вызвать admin-only массовый export и отправить в PATCH поле owner_id или is_vip, которого нет в форме. Одной скрытой кнопкой ни один из этих рисков не закрывается.

Частые вопросы о доступе

Что правильнее для чужого приватного объекта: 403 или 404?

Оба варианта возможны по контракту. 404 скрывает сам факт существования объекта, 403 явно сообщает об отказе. Главное — единая политика, отсутствие утечки и невозможность действия.

Если id — UUID, BOLA невозможна?

Нет. UUID снижает возможность перебора, но id может попасть в ссылку, лог, экспорт или другой ответ. Сервер обязан проверять право на каждый объект независимо от формата id.

Достаточно ли проверить роли через UI?

Нет. Скрытый элемент улучшает UX, но запрос можно отправить напрямую. Авторизация должна действовать на сервере для каждого метода и объекта.

Проверка доступа маленькая по шагам и большая по последствиям: иногда один изменённый id показывает, защищает ли backend пользовательские данные на самом деле.

Потренироваться на живых сервисах Следующий разбор

← Все разборы