Перейти к содержимому
DedicatedPHP Контакт

Как проверять права доступа в интеграционных тестах PHP

Преобразуйте правила доступа в интеграционные сценарии, проверяющие права, изоляцию пользователей и отсутствие несанкционированных побочных эффектов.

Матрица тестирования авторизации: пользователи, роли, ресурсы и разрешенные или запрещенные результаты

Возможность войти в систему не доказывает, что пользователь имеет право просматривать или изменять любые данные приложения. Аутентификация устанавливает личность пользователя; авторизация определяет, что он может делать, с каким ресурсом и при каких условиях. Маршрут может требовать действительную сессию и при этом позволять кому-либо прочитать заказ другого аккаунта, если не проверяется связь между пользователем и ресурсом.

Тесты авторизации в PHP должны проверять эту границу через точки входа, которыми пользуется приложение: например, HTTP-запрос к веб-маршруту или API. Цель — не проверить, как фреймворк реализует политики доступа, а подтвердить наблюдаемое поведение: кто что может делать, когда запрос отклоняется и какие данные остаются нетронутыми.

Преобразование правил доступа в матрицу

Преобразование правил доступа в матрицу — guía visual de DedicatedPHP

Прежде чем писать тесты, сформулируйте правила через четыре элемента: субъект, действие, ресурс и контекст. Контекст включает условия, изменяющие право доступа, например принадлежность к одной организации, владение записью или определенное состояние. Такая структура не позволяет свести авторизацию к списку ролей.

  • Субъект: анонимный пользователь, участник, руководитель или администратор.
  • Действие: чтение, создание, редактирование, удаление или утверждение.
  • Ресурс: заказ, документ, аккаунт или другой защищенный объект.
  • Контекст: владелец, организация, состояние ресурса или действующая связь.

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

Не нужно проверять все мыслимые сочетания. В первую очередь проверяйте границы доверия: пользователя без сессии, двух пользователей одной организации, пользователей разных организаций, пользователя с привилегированной ролью и ресурс, который ему не принадлежит. Добавьте особые контексты, меняющие решение, например архивный заказ, если для него действуют другие права, чем для активного.

Подготовка репрезентативных интеграционных сценариев

Подготавливайте данные явно и в небольшом объеме. Типичный тест может создать две организации, по одному пользователю в каждой и ресурс, связанный с одной из организаций. Затем выполните аутентификацию от имени пользователя, который пытается получить доступ, и отправьте запрос к публичному маршруту приложения, используя идентификатор ресурса. Так совместно проверяются точка входа, аутентификация, авторизация и ответ.

Для каждого важного правила включите как минимум один разрешенный и один запрещенный сценарий. Если пользователь-владелец может редактировать ресурс, проверьте, что разрешенное редактирование работает, а другой пользователь не может выполнить его. Положительный сценарий необходим: набор тестов, который проверяет только отказы, может пройти, даже если приложение блокирует и тех, кому доступ разрешен.

Также проверьте несуществующий ресурс. Ответ на неизвестный идентификатор может отличаться от ответа на существующий ресурс, к которому нет доступа. В некоторых приложениях используется ответ «не найдено», чтобы не раскрывать существование ресурса; в других сообщается, что доступ запрещен. Тест должен отражать намеренно выбранную политику продукта, а не навязывать универсальное соглашение.

Используйте фабрики, средства создания тестовых данных (фикстур) или вспомогательные функции, создающие корректные и понятные состояния. Не полагайтесь на фиксированные идентификаторы, порядок выполнения или общие данные, которые может изменить другой тест. Если проверяемое поведение включает сохранение данных, проверьте результат в базе данных с помощью обычных для проекта инструментов; не считайте, что успешный ответ сам по себе гарантирует правильное состояние.

Проверка изоляции пользователей и организаций

Для изоляции нужны отдельные сценарии, поскольку ошибки часто возникают при замене идентификатора в URL или теле запроса. Создайте ресурс одного аккаунта и запросите его чтение, редактирование или удаление от имени другого пользователя. Если в приложении данные разделены по компаниям, повторите проверку между организациями. Для критически важных операций проверяйте каждое действие: защита чтения не доказывает, что защищены также скачивание, экспорт или обновление.

Чтобы не дублировать весь набор тестов, вынесите общую подготовку данных и параметризуйте только те параметры, которые выражают правило. Например, список пар «субъект — ресурс» может задавать разрешенные сочетания. Используйте понятные названия конкретных сценариев: «участник другой организации не может редактировать заказ» объясняет больше, чем непрозрачный набор булевых значений. Разделяйте сценарии, если отличаются метод, маршрут или ожидаемые эффекты.

Не проверяйте каждое сочетание ролей с каждым ресурсом, если многие из них не соответствуют отдельным правилам. Вместо этого определите обоснованные эквивалентные случаи и оставьте явные проверки для исключений и границ. Если роли образуют иерархию, не предполагайте, что одна автоматически наследует все права другой: проверяйте фактическое правило, заданное продуктом.

Проверка ответов и побочных эффектов

При отказе проверьте и ответ, и то, что защищенная операция не была выполнена. В зависимости от интерфейса ответом может быть перенаправление, ответ со статусом неавторизованного доступа или запрета доступа либо ответ «ресурс не найден». Проверяйте соответствующий контракт — статус, формат и, если это важно, сообщение — не привязывая тест к несущественным деталям представления.

При отклоненном обновлении проверьте, что чувствительные поля не изменились. При удалении — что запись по-прежнему доступна. Если операция создает счет, уведомление или событие, убедитесь, что этот эффект также не возник. Проверки должны охватывать важные для бизнеса последствия, а не только HTTP-код.

Запрос без необходимых разрешений также не должен приводить к частичным изменениям. Если сценарий выполнения включает несколько операций, проверьте, что отказ происходит до внесения изменений или что транзакция оставляет систему в согласованном состоянии. Для этого не нужно изучать приватные методы: достаточно проверить ответ и сохраненные данные или эффекты.

Устойчивость тестов к изменениям реализации

Интеграционные тесты должны обращаться к стабильному интерфейсу приложения, например к маршруту, отправляя запрос от имени аутентифицированного пользователя с использованием доступных тестовых механизмов. Не вызывайте напрямую внутренний класс политик, если хотите проверить реальный доступ к ресурсу: так можно не проверить регистрацию маршрута, middleware или способ загрузки объекта.

При этом не превращайте набор тестов в копию всего приложения. Проверяйте контракт авторизации в репрезентативных точках, а модульные тесты оставьте для чистых правил, которым требуется много контекстных сценариев. Такое сочетание помогает находить ошибки: тест правила изолирует условие, а интеграционный тест подтверждает, что это правило защищает поток, предоставляемый приложением.

При изменении ролей, маршрутов или политик сначала пересмотрите матрицу, а затем обновляйте ожидаемые результаты. Тест, который меняют лишь для того, чтобы принять новый результат, может скрыть случайное расширение прав. Зафиксируйте причину изменения правила, определите, какие субъекты получают или теряют доступ, и добавьте сценарии, защищающие новые границы.

Контрольный список для проверки изменений

Контрольный список для проверки изменений — guía visual de DedicatedPHP
  • Определены ли субъект, действие, ресурс и контекст?
  • Есть ли для затронутого правила как минимум один разрешенный и один запрещенный сценарий?
  • Проверяется ли изоляция между пользователями или границами областей данных, если это применимо?
  • Проверяется ли несуществующий ресурс и выбранная политика, предотвращающая раскрытие информации?
  • Проходит ли запрос через точку входа, которая должна быть защищена?
  • Проверено ли, что отказ не изменяет данные и не создает побочных эффектов?
  • Изолированы ли тестовые данные, понятны ли они и воспроизводимы?
  • Отражают ли ожидаемые результаты решение продукта, а не случайную деталь фреймворка?

Полезный набор тестов не просто доказывает, что «права доступа существуют»: он показывает, что нужные сочетания работают, а запросы без необходимых разрешений не пересекают границу доступа. Матрица в сочетании с конкретными интеграционными тестами упрощает проверку изменений доступа и не привязывает безопасность к определенной внутренней реализации.

Хотите применить эти идеи в своем проекте?Давайте обсудим вашу PHP-платформу.
Посмотреть связанные услуги