АрхитектураАрхитектура безопасностиАрхитектор программного обеспечения

Практическая ситуация: интерфейс скрывает чужие документы, но клиент может отправить идентификатор другого ...

Практическая ситуация: интерфейс скрывает чужие документы, но клиент может отправить идентификатор другого документа. Какой компонент должен окончательно решать, разрешён ли доступ к документу?

Проходите собеседования с ИИ помощником Hintsage

Краткий ответ

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

Исторический контекст

Ранние системы часто полагались на доверенный клиент или сетевой периметр: считалось, что пользователь взаимодействует с приложением только через предусмотренный интерфейс. Распределённые системы, мобильные клиенты и публичные API показали, что клиент нельзя считать доверенным: запрос можно изменить, повторить или отправить напрямую.

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

Постановка проблемы

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

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

Подробное решение

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

Надёжная схема обычно включает следующие элементы:

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

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

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

Ситуация из практики

В системе совместной работы документы принадлежали организациям, а отдельные документы могли быть доступны приглашённым пользователям. Интерфейс корректно показывал только разрешённые документы, но API принимал идентификатор документа из запроса.

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

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

Что кандидаты часто упускают

  1. Чем объектная авторизация отличается от проверки роли пользователя?

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

  1. Почему проверку нельзя надёжно вынести только в шлюз API?

Шлюз защищает только маршруты, которые действительно через него проходят, и может не располагать всей доменной информацией. Внутренний вызов, задача очереди, административный инструмент или новый сервис способны обойти этот слой. Граница, на которой выполняется операция над защищённым объектом, должна иметь собственную проверку либо вызывать доверенный механизм, который гарантированно её выполняет.

  1. Как избежать утечки существования чужого объекта через ответы сервера?

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