При разработке расширений для системы 1С:Предприятие 8.3 программисты часто сталкиваются с необходимостью тонкой настройки прав доступа. Одним из механизмов, призванных упростить эту задачу, является опция Независимые права подчиненных объектов. Однако, как показывает практика и обсуждения на технических форумах, использование этого флага в ролях расширения может привести к серьезной уязвимости: пользователь получает права на изменение реквизитов, которые должны быть закрыты согласно логике основной конфигурации. В этой статье мы подробно разберем, почему это происходит, проанализируем механизм ошибки и найдем надежные способы обхода данной проблемы.
Рассмотрим стандартную ситуацию. В основной конфигурации у нас есть объект, например, справочник Контрагенты. В основной роли (входящей в поставку конфигурации) на этот справочник настроены права: чтение разрешено для всех реквизитов, а редактирование — только для одного, например, ИНН. Реквизиты КПП и ОГРН должны быть доступны только для просмотра.
Проблема проявляется, когда мы добавляем расширение и создаем в нем новую роль. Если в этой роли расширения мы заимствуем справочник Контрагенты и устанавливаем флаг Независимые права подчиненных объектов, платформа начинает интерпретировать права доступа иначе. Вместо ожидаемого объединения прав по принципу «ИЛИ», права на незаимствованные реквизиты могут «сбрасываться» в состояние «Разрешено все». В итоге пользователь в режиме «1С:Предприятие» внезапно получает возможность редактировать КПП и ОГРН, хотя основная конфигурация это явно запрещает.
Выясним причину такого поведения. Когда флаг Независимые права подчиненных объектов выключен, права расширения дополняют права основной конфигурации. Но при включении этого флага платформа ожидает, что права на подчиненные объекты (реквизиты, табличные части) будут заданы в этой роли явно. Если реквизит не заимствован в расширение, платформа в некоторых версиях (начиная с 8.3.22 и выше) ошибочно полагает, что ограничений на этот «невидимый» для расширения объект накладывать не нужно, особенно если в роли включена опция Устанавливать права для новых объектов.
Для того чтобы убедиться в наличии ошибки, разберем по шагам процесс воспроизведения проблемы, который подтвердили многие разработчики на версиях платформы 8.3.22.2283 и 8.3.23.1912:
ТестовыйСправочник с реквизитами Реквизит1 и Реквизит2.ОсновнаяРоль, где разрешим Изменение только для Реквизит1. Для Реквизит2 оставим только Просмотр.ТестовыйСправочник (без реквизитов).Расш_Роль, установим флаг Независимые права подчиненных объектов.В результате мы увидим, что Реквизит2 станет доступен для редактирования. Это происходит потому, что роль из расширения с «независимыми правами» перекрывает или некорректно суммируется с ограничениями основной роли для тех объектов, которые не были явно перенесены в область видимости расширения.
Самый простой и быстрый способ «починить» права — это заимствовать те реквизиты, на которые права работают некорректно, в само расширение. Разберем, как это работает:
Когда мы добавляем реквизит ОГРН в расширение, он становится «известен» роли расширения. Теперь, даже при включенном флаге независимых прав, платформа видит этот объект в метаданных расширения. Если в роли расширения права на этот заимствованный реквизит не будут установлены (флажки «Редактирование» сняты), платформа корректно применит ограничение, и пользователь снова потеряет возможность изменять данные, как и было задумано в основной конфигурации.
Плюсы: гарантированное решение проблемы для конкретного объекта.
Минусы: если справочник содержит десятки реквизитов, заимствование каждого из них значительно раздувает расширение и усложняет его дальнейшую поддержку при обновлении основной конфигурации.
Проанализируем еще одну важную настройку роли. В свойствах роли расширения часто по умолчанию стоит галочка Устанавливать права для новых объектов. При использовании независимых прав платформа может воспринимать реквизиты основной конфигурации, которых нет в расширении, как «новые» относительно контекста этой роли.
Попробуем следующий алгоритм:
Устанавливать права для новых объектов.В ряде случаев это позволяет избежать автоматического назначения полных прав на незаимствованные элементы метаданных.
Если специфика задачи позволяет, рассмотрим архитектурный подход. Опция Независимые права подчиненных объектов была спроектирована в первую очередь для управления правами новых объектов, созданных непосредственно в расширении.
Рекомендуется следовать правилу: Не использовать независимые права в ролях расширения для объектов, которые заимствованы из основной конфигурации.
Если вам нужно добавить права на новый реквизит, созданный в расширении, лучше создать для него отдельную роль в этом же расширении. Для заимствованных объектов используйте стандартные роли расширения без флага независимых прав — тогда механизмы платформы будут работать в классическом режиме суммирования прав «ИЛИ», что гораздо предсказуемее и безопаснее.
Важно помнить, что данная ошибка платформы затрагивает не только видимость полей. Мы должны учитывать, что включение независимых прав может «ослеплять» механизмы RLS. Если в основной конфигурации на объект наложены сложные условия ограничения (например, по подразделениям или организациям), роль расширения с независимыми правами может игнорировать эти условия, предоставляя пользователю доступ ко всем записям таблицы (Select All).
Проверим это программно с помощью функции ПравоДоступа():
// Проверка прав на редактирование реквизита
Результат = ПравоДоступа("Изменение", Метаданные.Справочники.Контрагенты.Реквизиты.КПП);
Если Результат Тогда
Сообщить("Внимание: обнаружена дыра в безопасности, реквизит доступен на запись!");
КонецЕсли;
Если программная проверка возвращает Истина, значит, проблема не в визуальном отображении формы, а в реальном распределении прав на уровне ядра платформы. В таком случае использование Варианта №1 (заимствование реквизитов) становится обязательным до момента выхода официального патча от фирмы 1С.
Мы рассмотрели коварную особенность платформы, которая может привести к несанкционированному изменению данных. Подведем итоги нашего анализа:
При проектировании систем безопасности всегда проверяйте итоговые права пользователя через консоль прав или программно, так как поведение расширений в части прав доступа остается одной из самых сложных и изменчивых зон в развитии платформы 1С.