Как УстановитьПривилегированныйРежим(ИСТИНА) взаимодействует с ВЫБРАТЬ РАЗРЕШЕННЫЕ в запросах 1С и отключает ли он RLS?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При работе с платформой 1С:Предприятие часто возникают вопросы о взаимодействии различных механизмов, особенно когда речь идет о правах доступа. Один из таких вопросов касается совместного использования функции УстановитьПривилегированныйРежим(ИСТИНА) и ключевого слова ВЫБРАТЬ РАЗРЕШЕННЫЕ в запросах. Давайте разберем эту ситуацию по шагам, чтобы полностью понять, как они работают и влияют друг на друга, особенно в контексте ограничений прав доступа на уровне записей (RLS).

Понимание функции УстановитьПривилегированныйРежим(ИСТИНА)

Для начала, давайте рассмотрим, что представляет собой функция УстановитьПривилегированныйРежим(ИСТИНА) и для чего она предназначена. Эта процедура глобального контекста активирует так называемый привилегированный режим выполнения кода на сервере.

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

  1. Игнорируются проверки прав доступа к объектам метаданных, таким как справочники, документы или регистры.
  2. Обходятся механизмы ограничения прав на уровне записей (RLS), которые обычно фильтруют данные, доступные пользователю.
  3. Игнорируются проверки на уровне объектов.

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

Рассмотрим важные особенности использования привилегированного режима:

  1. Локальный характер: Режим не является глобальным для всего сеанса. Он действует только в пределах вызывающего кода и всех его вложенных вызовов, пока не будет явно отключен.
  2. Обязательное отключение: Крайне важно всегда отключать привилегированный режим после завершения блока кода, используя УстановитьПривилегированныйРежим(Ложь). Это необходимо делать даже в случае возникновения исключений, поэтому рекомендуется оборачивать такой код в конструкцию Попытка...Исключение...КонецПопытки, чтобы гарантировать отключение режима.
  3. Баланс вызовов: Количество вызовов УстановитьПривилегированныйРежим(ИСТИНА) и УстановитьПривилегированныйРежим(Ложь) должно строго совпадать. Если вызвать УстановитьПривилегированныйРежим(Ложь) больше раз, чем было включено, будет вызвано исключение.
  4. Автоматическое отключение: Привилегированный режим автоматически выключится при возврате из функции или процедуры, в которой он был включен, если он не был явно отключен вручную.

Давайте также проанализируем контекст выполнения, поскольку это критически важно:

  1. Серверное выполнение: На сервере привилегированный режим используется в большинстве случаев, так как клиентские сеансы ограничены в доступе к данным и могут только вызывать серверные процедуры.
  2. Клиентский вызов: В клиент-серверном варианте работы информационной базы вызов УстановитьПривилегированныйРежим(ИСТИНА) на клиенте не приведет к его включению. Он сработает только при исполнении серверного кода.
  3. Исключения и ограничения: Существует несколько сценариев, при которых привилегированный режим может быть не установлен:
    • Если попытка вызова происходит из внешней обработки, у которой включена защита от опасных действий для текущего пользователя.
    • Если информационная база работает в клиент-серверном режиме, а в консоли кластера серверов в свойствах информационной базы для профиля безопасности не выбран флаг "к привилегированному режиму".
    • Внешние обработки по умолчанию запускаются в безопасном режиме, который игнорирует попытки включения привилегированного режима. Отключить безопасный режим для внешней обработки можно только через менеджер внешних обработок (кодом из конфигурации).
  4. Общие модули и объекты: Для общих модулей можно установить свойство "Привилегированный" непосредственно в конфигурации, чтобы весь код внутри них исполнялся без проверки прав. Аналогично, для документов и бизнес-процессов есть свойства конфигурации, позволяющие автоматически устанавливать привилегированный режим при проведении/отмене проведения документов и создании задач бизнес-процессов соответственно.

Понимание ключевого слова ВЫБРАТЬ РАЗРЕШЕННЫЕ

Теперь обратимся к конструкции ВЫБРАТЬ РАЗРЕШЕННЫЕ в языке запросов 1С. Это ключевое слово предназначено для использования в сценариях, где применяются ограничения прав доступа на уровне записей (RLS).

Давайте выясним поведение запроса без ВЫБРАТЬ РАЗРЕШЕННЫЕ:

Если в запросе мы выбираем данные, и у пользователя настроен RLS, при этом конструкция ВЫБРАТЬ РАЗРЕШЕННЫЕ не используется, то при попытке получить записи, на которые у пользователя нет прав, платформа сгенерирует ошибку. Обычно это ошибка типа "У пользователя недостаточно прав на исполнение операции над базой данных". Это сделано для того, чтобы исключить ситуации, когда пользователь получает неполные данные и делает на их основе неверные выводы.

И наоборот, рассмотрим поведение запроса с ВЫБРАТЬ РАЗРЕШЕННЫЕ:

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

Важно помнить, что хотя ВЫБРАТЬ РАЗРЕШЕННЫЕ предотвращает ошибки, оно может привести к отображению недостоверной или неполной информации в отчетах или формах. Если мы ожидаем получить полный набор данных, а получаем только доступные пользователю, это может ввести в заблуждение, так как никаких явных сообщений об ограничении данных не будет.

Взаимодействие УстановитьПривилегированныйРежим(ИСТИНА) и ВЫБРАТЬ РАЗРЕШЕННЫЕ

Теперь, когда мы понимаем суть каждого механизма по отдельности, давайте разберем их взаимодействие, что и было основным вопросом автора. Отвечая прямо на вопрос из темы: "ВЫБРАТЬ РАЗРЕШЕННЫЕ все равно будет через RLS работать?" и "Такая обертка отключает RLS для ВЫБРАТЬ РАЗРЕШЕННЫЕ?", мы можем уверенно сказать следующее:

Если код выполняется в привилегированном режиме, то есть внутри блока, ограниченного вызовами УстановитьПривилегированныйРежим(ИСТИНА) и УстановитьПривилегированныйРежим(Ложь), то все ограничения прав, включая RLS, игнорируются полностью. Это означает, что запросы, выполненные в этом режиме, будут возвращать все данные, независимо от того, какие права доступа настроены для текущего пользователя.

Следовательно, в привилегированном режиме использование ключевого слова ВЫБРАТЬ РАЗРЕШЕННЫЕ становится избыточным. Запрос вернет полный набор данных, как если бы ВЫБРАТЬ РАЗРЕШЕННЫЕ не использовалось вовсе, и как если бы у пользователя были полные права на все записи. Мы не получим ошибку, если у пользователя нет прав, и мы получим все записи, даже если RLS накладывает ограничения.

Давайте посмотрим на пример кода, который был предложен в обсуждении:


УстановитьПривилегированныйРежим(ИСТИНА);
    РезультатЗапроса = Запрос.Выполнить();
УстановитьПривилегированныйРежим(Ложь);

Внутри этой "обертки" любой запрос, даже если он содержит ВЫБРАТЬ РАЗРЕШЕННЫЕ, будет выполнен без учета RLS. То есть, ВЫБРАТЬ РАЗРЕШЕННЫЕ не будет выполнять свою функцию фильтрации по правам, так как механизм RLS уже отключен привилегированным режимом. Результат запроса будет содержать все данные, к которым у пользователя в обычном режиме не было бы доступа.

Особенности контекста выполнения и потенциальные риски

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

Контекст выполнения

Мы уже упоминали, что функция УстановитьПривилегированныйРежим() работает только на сервере. Некоторые участники обсуждения справедливо отмечают, что ее поведение может отличаться в специфических сценариях:

  1. Внешние обработки: По умолчанию внешние обработки запускаются в безопасном режиме. В таком режиме попытки включить привилегированный режим игнорируются, как подтверждают сообщения 9 и 12. Чтобы привилегированный режим заработал во внешней обработке, ее нужно запускать через механизм дополнительных отчетов и обработок, предварительно отключив для нее безопасный режим в конфигурации или через менеджер внешних обработок.
  2. Расширения в безопасном режиме: Аналогично внешним обработкам, если расширение или часть его кода выполняется в безопасном режиме, привилегированный режим может не быть установлен.
  3. Профиль безопасности: Как было упомянуто, даже на сервере привилегированный режим может быть заблокирован настройками профиля безопасности в консоли кластера серверов 1С.

Поэтому, когда мы пишем код с УстановитьПривилегированныйРежим(ИСТИНА), нам всегда следует учитывать, где и как он будет выполняться.

Риск "битых ссылок" и проблемы безопасности

Одно из критически важных замечаний прозвучало в сообщении 11, где говорится о возможности получения "битых ссылок" при выходе из привилегированного режима. Давайте разберем этот момент подробнее:

Представьте, что в привилегированном режиме мы получили ссылку на объект (например, на элемент справочника), на который у пользователя в обычном режиме нет прав. Если мы затем передадим этот объект за пределы блока привилегированного режима и попытаемся обратиться к его свойствам или методам (например, получить наименование, код и т.д.), то при попытке выполнения таких действий уже в пользовательском режиме (без полных прав), мы можем получить ошибку доступа или так называемую "битую ссылку". Система не даст нам получить данные из объекта, к которому у пользователя нет прав, даже если сама ссылка на объект была получена законно в привилегированном режиме.

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

  1. Точечное использование: Включайте привилегированный режим максимально точечно, только для тех действий, где это абсолютно необходимо, и сразу же отключайте его после выполнения нужных операций.
  2. Конвертация данных: Если в привилегированном режиме мы получаем данные, которые затем будут использоваться в пользовательском режиме, и эти данные могут быть недоступны пользователю, преобразуйте их в простые типы (строки, числа) до выхода из привилегированного режима. Как было замечено в сообщении 11, часто в 1С:ЗУП так делают для печатных форм приказов: данные получают в привилегированном режиме, переводят их в строки и затем печатают, а при необходимости переезда в новую базу используют инструмент для переноса данных между базами 1С:ЗУП 3.
  3. Дополнительные проверки: Перед выполнением действий в привилегированном режиме, а также после получения данных, мы можем использовать метод ВыполнитьПроверкуПравДоступа(), чтобы убедиться, что пользователь имеет достаточные права для выполнения операции, если это требуется по логике.
  4. Безопасность данных: Неоправданное и неконтролируемое использование привилегированного режима может привести к серьезным проблемам безопасности пользовательских данных, включая нежелательные изменения в базе данных или утечку конфиденциальной информации. Всегда осознавайте последствия включения привилегированного режима.

В итоге, мы выяснили, что УстановитьПривилегированныйРежим(ИСТИНА) полностью отключает RLS для всех запросов, выполняемых внутри его действия, делая ВЫБРАТЬ РАЗРЕШЕННЫЕ избыточным. Привилегированный режим дает полный доступ к данным, но требует крайне осторожного и осознанного применения, чтобы избежать уязвимостей и ошибок.

← На главную