Какой риск возникает, когда сервис с привилегиями выполняет действие по просьбе пользователя, используя только собственную учётную запись?
Возникает риск «замешательства заместителя»: пользователь может заставить привилегированный сервис выполнить действие, на которое сам не имеет права. Сервис видит разрешённого технического вызывающего, но теряет информацию о фактическом инициаторе операции.
Нужно передавать и проверять контекст конечного пользователя или делегированное полномочие, а не полагаться только на идентичность сервисной учётной записи.
Проблема появилась из-за посредников, которые действуют от имени других субъектов и обладают большими полномочиями, чем эти субъекты. Такой посредник удобен для централизации доступа, но создаёт границу, на которой легко перепутать полномочия самого сервиса с полномочиями пользователя.
Концепция confused deputy стала общей моделью для анализа подобных ошибок в операционных системах, файловых системах, сетевых службах и распределённых приложениях. Она показывает, что одной проверки подлинности вызывающего сервиса недостаточно: необходимо сохранять причинно связанную с запросом идентичность инициатора.
Предположим, пользователь может попросить сервис сформировать отчёт или изменить ресурс. Сервис имеет широкие права для работы с данными и обращается к внутреннему хранилищу только от своего имени.
Если внутреннее хранилище проверяет лишь сервисную учётную запись, пользователь получает косвенный доступ ко всем операциям, разрешённым сервису. Последствия включают чтение чужих данных, изменение ресурсов, обход разделения арендаторов и повышение привилегий через доверенный посредник.
Особенно опасны операции, где пользователь управляет параметрами объекта, идентификатором владельца или назначением действия. Ограничение интерфейса не устраняет риск, если сам сервис способен выполнить более широкую операцию.
Архитектура должна различать как минимум два субъекта: сервис-исполнитель и конечного пользователя. Первый отвечает за техническое право вызвать внутреннюю функцию, второй — за бизнес-право совершить конкретное действие над конкретным ресурсом.
Практический механизм обычно включает следующие элементы:
Передача идентификатора пользователя в произвольном заголовке не является достаточной защитой: такой заголовок может быть подменён или ошибочно принят доверенным. Нужен защищённый механизм делегирования, например подписанный контекст или специальный токен обмена, причём внутренний сервис должен доверять только известному источнику и проверять аудиторию токена.
Есть важный компромисс. Сквозная передача пользовательского контекста повышает точность авторизации и аудита, но усложняет управление сроком жизни токенов, отзывом полномочий, трассировкой и отказоустойчивостью. Иногда сервису действительно нужно работать от собственного имени, например для фоновой обработки; тогда это должно быть отдельное явно разрешённое действие, не замаскированное под пользовательский запрос.
Журналы должны фиксировать как минимум кто инициировал действие, какой сервис его выполнил и какой ресурс был затронут. Иначе расследование покажет только привилегированный сервис и не позволит надёжно определить источник операции.
Сервис поддержки позволял оператору запросить экспорт данных клиента. Он обращался к хранилищу с собственной сервисной учётной записью, имевшей право экспортировать данные любого клиента. Идентификатор клиента поступал из запроса оператора, а хранилище не знало, кто именно инициировал операцию.
Рассматривались два варианта. Первый — создать отдельные сервисные учётные записи для каждого оператора; это плохо масштабируется, усложняет ротацию секретов и не решает вопрос динамических бизнес-правил. Второй — оставить широкие права сервису и проверять оператора только в интерфейсе; этот вариант не защищает внутреннюю границу от ошибочного или вредоносного вызова.
Выбрали делегирование: сервис поддержки передавал во внутренний сервис подписанный контекст оператора с ограниченной операцией, целевой системой, сроком действия и идентификатором клиента. Внутренний сервис самостоятельно проверял полномочия оператора на экспорт конкретного клиента, а сервисная учётная запись имела только техническое право выполнить уже разрешённый экспорт.
В результате проверка стала независимой от пользовательского интерфейса, а аудит получил разделение между инициатором и исполнителем. Дополнительной защитой стали короткий срок жизни делегированного контекста и запрет его использования для других внутренних сервисов.
Нет. Обычное поле или заголовок с идентификатором не доказывает, что значение сформировал доверенный компонент и что оно относится именно к текущему действию. Контекст должен быть защищён от подмены, связан с конкретным запросом или делегированным полномочием и проверен принимающим сервисом.
Нет. Это подтверждает лишь техническую идентичность посредника. Если посредник обладает более широкими правами и не передаёт проверяемый контекст пользователя, он остаётся потенциальным «замешанным заместителем». Проверка сервиса нужна, но для пользовательских операций она дополняется проверкой субъекта, ресурса и действия.
Не обязательно. Важно, чтобы компонент, принимающий решение об авторизации, располагал достоверным контекстом, достаточным для этого решения. В некоторых архитектурах решение принимает промежуточный сервис, а следующий получает уже узко ограниченное делегированное право; однако границы доверия, область действия и ответственность за ошибочную авторизацию должны быть явно определены.