Как стать автором
Обновить
200.52
Postgres Professional
Разработчик СУБД Postgres Pro

Как в СУБД реализовать администратора без прав доступа к данным

Уровень сложностиСредний
Время на прочтение9 мин
Количество просмотров7K

В СУБД-строении есть не новая, но не теряющая актуальности задача. Сформулировать её можно примерно так: как убрать возможность суперпользователя взаимодействовать с данными, но оставить ему все возможности по управлению СУБД? Эта функция затребована не только большими компаниями с жёсткими требованиями к информационной безопасности, но и крайне нужна всем, кто попадает под различного вида государственные регуляции, вроде приказа ФСТЭК №64 или страшного GDPR.

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

В этой статье мы хотим поговорить о том, какие есть подходы к решению этой проблемы, какие можно найти реализации на рынке, и что решили сделать мы в Postgres Professional.

Одним из возможных решений данной задачи является введение классической ролевой модели, в рамках которой нас интересует выделение следующих ролей:

  • Администратор СУБД;

  • Администратор БД (он же владелец данных);

  • Администратор безопасности.

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

  • Администратор безопасности должен быть ограничен в возможностях DDL, DML, DCL;

  • Полномочия суперпользователя должны быть распределены между  администраторами этой модели;

  • Необходим механизм защиты от несанкционированного доступа самими администраторами к конфиденциальной информации;

  • Механизм защиты от самостоятельного повышения привилегий.

Как это сделано в Oracle

В Oracle реализация модели разделения полномочий администраторов возложена на модуль Oracle Database Vault (ODV). Он предотвращает несанкционированные изменения в базе данных и контролирует доступ администраторов к различной информации. Фактически, он предоставляет роли, которые позволяют пользователям выполнять определённые задачи, не предоставляя им прав больше, чем требуется для конкретного действия.

Основные роли в данной реализации это:

  • DV_OWNER (владелец данных) и DV_ADMIN (администратор безопасности). Позволяют создавать политики баз данных и управлять ими.

  • DV_ACCTMGR. Главный администратор безопасности. Управляет товарищами из пункта выше.

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

Также Oracle Database Vault позволяет создать дополнительный набор компонентов для управления безопасностью. Например, защищённая область (хотя по-английски она называется realm). Это область в базе данных, в которой могут быть защищены схемы и другие объекты этой базы. Например, можно отдельно защитить схемы и объекты связанные с HR, продажами и бухгалтерией. Не то чтобы данные других отделов не надо было защищать, просто эти, в нашей модели угроз, могут быть отнесены к особо чувствительным данным и требовать отдельного к ним отношения. И ODV позволяет нам управлять правами доступа к ним с крайне высокой степенью гранулярности: роли, не введенные в домен доступа, не смогут взаимодействовать с объектами внутри него.

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

Иллюстрация модели реализации ограничения доступа в Oracle Database Vault
Иллюстрация модели реализации ограничения доступа в Oracle Database Vault

Итого, можно смело сказать, что в Oracle реализовали классную модель с одним только значимым минусом — очень сложно проводить её аудит из-за сложности организации доменной структуры. Однако на первом месте у нас безопасность данных, так что стиснув зубы будем проводить аудит, но зато спать спокойно.

Что придумали в PostgreSQL или дилемма суперпользователя

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

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

  • По отношению к защищенным таблицам у него не должно быть возможности выполнять:

SELECT
UPDATE
INSERT
TRUNCATE
DROP
DELETE
  • Суперпользователь не должен создавать и назначать роли, поэтому под нож идут:

CREATE ROLE
DROP ROLE
ALTER ROLE
DROP OWNED
GRANT
REASSIGN OWNED
SET ROLE
SET SESSION AUTHORIZATION
ALTER TABLE.

Как мы обсудили ранее, в рамках нашей модели Администратор безопасности должен иметь возможность управлять доступами пользователей к защищённым объектам, но не может создавать и удалять объекты и самих пользователей. Как и не может управлять доступами вне защищённых объектов. В это время Администратор СУБД берёт на себя весь жизненный цикл управления пользователями, но не может выдавать права на защищаемые объекты.

И тут начинается самое интересное: нам предстоит проанализировать все (буквально все) возможные сценарии использования системных функций доступных суперпользователю. Для понимания объёма работ, в одном только файле aclchck.c (src/backend/catalog) существует 37 функций доступных лишь суперпользователю. И сверху, в дополнение к стандартным ACL надо создать новые сущности для дополнения существующих, но предназначенных только для суперпользователя.

Список из тех самых 37 функций

pg_class_aclmask_ext();
pg_database_aclmask();
pg_parameter_aclmask();
pg_parameter_acl_aclmask();
pg_proc_aclmask();
pg_language_aclmask();
pg_largeobject_aclmask_snapshot();
pg_namespace_aclmask();
pg_tablespace_aclmask();
pg_foreign_data_wrapper_aclmask();
pg_foreign_server_aclmask();
pg_type_aclmask();
pg_class_ownercheck();
pg_type_ownercheck();
pg_oper_ownercheck();
pg_proc_ownercheck();
pg_language_ownercheck();
pg_largeobject_ownercheck();
pg_namespace_ownercheck();
pg_tablespace_ownercheck();
pg_opclass_ownercheck();
pg_opfamily_ownercheck();
pg_ts_dict_ownercheck();
pg_ts_config_ownercheck();
pg_foreign_data_wrapper_ownercheck();
pg_foreign_server_ownercheck();
pg_event_trigger_ownercheck();
pg_database_ownercheck();
pg_collation_ownercheck();
pg_conversion_ownercheck();
pg_extension_ownercheck();
pg_publication_ownercheck();
pg_subscription_ownercheck();
pg_statistics_object_ownercheck();
has_createrole_privilege();
has_bypassrls_privilege().

Однако ничто не идеально, особенно в мире СУБД. Есть общая для всех СУБД проблема на архитектурном уровне, возникающая как следствие гибкости — одно и то же действие можно выполнить различными способами. Особенно, если речь о суперпользователе. Строго говоря, задача по описанию возможных вариантов его доступа к защищённым данным достаточно сложна и плохо формализуется. Хотя верхнеуровнево она звучит весьма просто — определить множество действий, которые явно запрещены. Некоторые вендоры СУБД заявляют, что им удалось реализовать такой подход во всей полноте, но, как в анекдоте, есть нюанс: доказательств полноты проведённых тестов в публичном поле не публиковалось. Джентльмены, конечно, никогда не врут, но сей факт заставляет задуматься.

Просто для примера. В постгресе юзер может выполнить SELECT при наличии соответствующего ACL. Суперпользователь, как мы договорились выше, не сможет сам себе назначить права с помощью GRANT и REVOKE, однако опосредованно через системный каталог можно сделать несколько ловких финтов ушами.

  1. Информацию о таблицах и столбцах можно вытащить из information_schema.columns

SELECT table_name, column_name, data_type 
FROM information_schema.columns 
WHERE table_schema = 'public' AND table_name = 'protected_table';
  1. Таблица pg_tables позволяет получить список таблиц в схеме

SELECT tablename 
FROM pg_tables 
WHERE schemaname = 'public'; 
  1. Таблицы pg_constraint и pg_attribute отлично отдают информацию о ключах

SELECT conname, conrelid::regclass AS table_name, a.attname AS column_name
FROM pg_constraint c 
JOIN pg_attribute a ON a.attnum = ANY(c.conkey) 
WHERE confrelid = 'protected_table'::regclass; 
  1. А с помощью такого запроса к таблице information_schema.role_table_grants можно узнать о привилегиях на конкретную таблицу:

SELECT grantee, privilege_type, table_name, table_schema 
FROM information_schema.role_table_grants 
WHERE table_name = 'protected_table' AND table_schema = 'public'; 

И это — лишь один из возможных путей, которым может воспользоваться суперпользователь, следуя тёмным замыслам. Так что, при наличии желания, извернуться можно весьма по-разному. Например, суперпользователь может даже выдать права на чтение из защищенной таблицы через изменение системных таблиц PostgreSQL:

INSERT INTO pg_class (relname, relnamespace, reltype, relowner, relam, relfilenode, reltablespace, relpages, reltuples, relallvisible) VALUES ('protected_table', 'your_schema'::regnamespace, 0, (SELECT oid FROM pg_roles WHERE rolename = 'your_role'), 0, 0, 0, 0, 0, 0);

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

Отказ от суперпользователя

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

У нас получился примерно такой список:

  1. Администратор СУБД;

  2. Администратор БД;

  3. Администратор безопасности;

  4. Обычный пользователь;

  5. Привилегированный пользователь с доступом к конфиденциальной информации.

Теперь немного разберём основные моменты. Администратор СУБД, как обычно, самый важный юзер. В его права и обязанности входит:

  • Управление сервером;

  • Настройка репликации данных и резервного копирования;

  • Создание баз данных;

  • Настройка соединений с БД Postgres;

  • И, самое главное, назначение Администраторов БД.

В свою очередь, Администратор БД отвечает за:

  • Резервное копирование отдельной базы;

  • Создание таблиц и других объектов в рамках отдельной БД;

  • Создание пользователей БД;

  • Наделение пользователей правами доступа, кроме доступа к конфиденциальной информации.

За последний пункт у нас отвечает отдельная роль: Администратор безопасности.

Это были администраторы, а теперь — что касается других пользователей. Обычный пользователь БД имеет доступ к своим таблицам и таблицам других пользователей (если нет запрещающих ACL, конечно же). А привилегированный в рамках конкретной базы может иметь доступ к защищённым данным в своих таблицах.

Прекрасная получается модель, схожая с описанным в начале статьи запрещающим методом, остаётся только реализовать.

Путь Postgres Pro — СУБД без суперпользователя

Идея по отказу от роли суперпользователя зародилась в сообществе ещё до выхода релиза PostgreSQL 16 версии. Желающие могут ознакомиться с заметкой Роберта Хааса, от января 2023.

Суперпользователь был придуман давно, когда требования к СУБД были гораздо мягче и никто особо не задумывался, что пользователь с такими правами не удовлетворяет базовым принципам информационной безопасности. А именно, разделению полномочий и минимизации привилегий. Но всё течёт, всё меняется, и вот вы дочитываете статью о том, как теперь нам жить вовсе без суперпользователя. 

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

С другой стороны, путь отказа от роли суперпользователя требует только проверки возможности обслуживания СУБД без оного. А это уже вполне конкретный пул задач и действий, которые достаточно легко проверяются. Собственно, поэтому мы и выбрали этот подход, как имеющий доказуемую безопасность.

Для справедливости отметим, что вырезать на корню суперпользователя у нас не получилось. Его помощь всё ещё может понадобиться при решении очень редки и, особенно сложных задач — по сути, в случае форс-мажоров. Он всё ещё доступен в singlemode режиме, но не может войти даже в него без участия других администраторов. Всё это позволяет нам утверждать, что это совершенно точно нельзя назвать штатным режимом работы, когда злоумышленник сможет незаметно нанести ущерб. И да, в штатном режиме суперпользователь отключен и не может даже авторизоваться.

Нами был определен перечень задач и действий, требующих полномочий суперпользователя. В СУБД были внесены изменения — добавлены специальные новые предопределённые роли: 

  • pg_create_tablespace, позволяющая выполнять команду CREATE TABLESPACE без прав суперпользователя;

  • pg_manage_profiles, позволяющая выполнять команды CREATE PROFILE, ALTER PROFILE и DROP PROFILE без прав суперпользователя. 

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

В соответствии с принятой ролевой моделью для ограничения доступа к данным были введены защищаемые сущности, доступ к которым ограничивается в соответствии с ролевой моделью PostgreSQL. Однако в качестве минимальной единицы, подлежащей защите, была выбрана не таблица, а схема. Выбор схемы в качестве минимальной единицы защиты обусловлен тем, что в СУБД схема уже является логической единицей, объединяющей структуры и данные по их функциям и задачам. Выбор в качестве защищаемых объектов таблиц или строк в значительной мере затруднит аудит таких объектов в будущем, а также приведёт к риску пропустить (а то даже и «забыть») настройку доступа к какому-то элементу защищённых сущностей, вынесенных в отдельную таблицу или вьюху.

И самое-то главное сказать забыли: весь описанный подход реализован нами в 16 версии СУБД Postgres Pro Enterprise и Postgres Pro Enterprise Certified.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Авторы статьи:

Василий Бернштейн, Старший технический менеджер продукта, Postgres Professional.

Владимир Абрамов, Старший инженер по информационной безопасности, Postgres Professional.

Валерий Попов, Руководитель отдела информационной безопасности, Postgres Professional.

Теги:
Хабы:
Если эта публикация вас вдохновила и вы хотите поддержать автора — не стесняйтесь нажать на кнопку
Всего голосов 18: ↑18 и ↓0+18
Комментарии12

Публикации

Информация

Сайт
www.postgrespro.ru
Дата регистрации
Дата основания
Численность
201–500 человек
Местоположение
Россия
Представитель
Иван Панченко