Перейти к основному содержимому

Маскирование запросов

Описание

В СУБД Pangolin для обеспечения защиты персональных данных и конфиденциальных сведений при выполнении SQL-запросов реализована функциональность маскирования запросов. Модель функционирования СУБД строится на выполнении запросов со стороны аутентифицированных и авторизованных пользователей.

Тексты SQL-запросов при выполнении могут быть выведены в лог или служебные представления СУБД в неизмененном виде (в соответствии с настройками СУБД или расширений, выполняющих обработку запросов). При этом информация может содержать данные:

  • разглашение которых нежелательно, по причине содержания в них конфиденциальной информации;

  • раскрытие которых может предоставлять возможность несанкционированного доступа к СУБД;

  • которые не должны быть доступны администраторам БД или администраторам ОС, имеющим доступ к файлам логов, но не имеющим доступ к БД:

    • пароли (при выполнении запросов на управление ролями и пользователями, включая задание параметров аутентификации и авторизации);
    • данные о структуре БД (при выполнении запросов на управление структурой хранимых данных, включая БД, схемы, табличные пространства, объекты схем);
    • хранимые данные в БД (при выполнении действий над хранимыми данными, таких как выборка, вставка, изменение и удаление).

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

Назначение

Известные для СУБД Pangolin точки, в которых может быть выполнен вывод пользовательских запросов, следующие:

Текст запросаСценарийУсловиеИнициатор запроса
Полный текст запроса, соответствующего условиюПри выводе в лог сразу после получения запросаПараметр log_statement=условиеАдминистратор СУБД;
пользователь ОС, имеющий доступ к файлам логов
Полный текст запроса, соответствующего условиюПри выводе в лог сразу после получения запросаПараметр log_min_duration_statement=минимальная длительностьАдминистратор СУБД;
пользователь ОС, имеющий доступ к файлам логов
Полный текст запроса + ошибочная лексема при ошибке разбораПри выводе сообщения в лог, в том числе при ошибкеПараметр log_min_error_statement=уровень логирования, для записей лога с уровнем логирования равным или выше указанногоАдминистратор СУБД;
пользователь ОС, имеющий доступ к файлам логов
Урезанный до 1024 символов текст любого запросаПри запросе из представления pg_stat_activityПо своей сессии, запросе пользователем с ролью pg_read_all_stats или суперпользователемАдминистратор СУБД;
авторизованный пользователь
Запрос на задание или изменение пароля с паролемПри сохранении в файл pg_stat_tmp/pgss_query_texts.stat. При запросе из представления pg_stat_statementsУстановленное расширение pg_stat_statements, при запросе пользователем с ролью pg_read_all_stats или суперпользователемАдминистратор СУБД;
авторизованный пользователь ОС, имеющий доступ к файлу pg_stat_tmp/pgss_query_texts.stat
Урезанный до 1024 символов текст любого запроса, выполнение которого попало на момент формирования среза сессий со стороны ASH (performance insight)При сохранении в файлы ASH. При запросе из представления ASHБез ограниченийАдминистратор СУБД;
авторизованный пользователь ОС, имеющий доступ к файлам ASH
Полный текст запроса, соответствующего условиюПри выводе в лог результат работы расширения auto_explainУстановленное расширение auto_explain, соответствие запроса параметрам расширенияАдминистратор СУБД;
пользователь ОС, имеющий доступ к файлам логов
Полный текст запроса, соответствующего условиюПри выводе в лог результат работы расширения pg_hint_planУстановленное расширение pg_hint_plan, соответствие запроса параметрам расширения, при значении параметра pg_hint_plan.debug_print большем, чем onАдминистратор СУБД;
пользователь ОС, имеющий доступ к файлам логов
Полный текст запроса, соответствующего условию аудитаПри выводе в лог записей аудита, соответствующих критериям аудитаСоответствие сессии и/или запроса заданным критериям аудитаАдминистратор СУБД;
пользователь ОС, имеющий доступ к файлам логов (содержащих, среди прочего, записи лога аудита)

Выполняемые запросы могут содержать следующую информацию, которая не должна быть доступна администраторам СУБД (superuser) или лицам, имеющим доступ к файлам логов, но не имеющим доступ к БД (администраторы ОС):

  • значения паролей или хешей паролей в запросах на задание или изменение паролей пользователей;
  • значения параметров-паролей в функциях API администраторов безопасности;
  • явно заданные как константы значения параметров в функциях;
  • явно заданные как константы значения, вставляемые (INSERT) в таблицы и представления, в том числе заданные через выражения SELECT или CTE;
  • явно заданные как константы значения, задаваемые для изменения полей (UPDATE) в таблицах и представлениях, или используемые для фильтрации записей для изменения;
  • явно заданные как константы значения, задаваемые как условия выражений SELECT, UPDATE и DELETE по полям таблиц и представлений.

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

  • выводе запроса в лог по условию log_statement=условие, влияет на попадание в лог запросов определенных типов — либо dll (только запросы DDL), либо mod (запросы DDL, модификации данных и COPY FROM), либо all (все запросы);
  • выводе запроса в лог по условию log_min_duration_statement=минимальная длительность, влияет на попадание в лог запросов с определенной длительностью;
  • выводе запроса в лог при ошибке по условию log_min_error_statement=уровень логирования запросов, влияет на попадание в лог запросов определенных типов;
  • накоплении и получении текстов запросов из представления pg_stat_activity;
  • накоплении, сохранении в файл pg_stat_tmp/pgss_query_texts.stat и получении запросов из представления pg_stat_statements;
  • выводе в лог информации об обрабатываемых запросах от расширения auto_explain;
  • выводе в лог информации об обрабатываемых запросах от расширения pg_hint_plan;
  • выводе в лог (аудита) в соответствии с критериями аудита, включая значения параметров подготовленных запросов при pgaudit.log_parameter = on.

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

Внимание!

Сохранение текста запроса в файлы ASH (performance insight) - регулируется собственными параметрами performance insight и performance_insights.masking.

При этом при заданном маскировании запросов (masking_mode = full) маскирование запросов в ASH (performance insight) будет выполняться независимо от значения параметра performance_insights.masking. Это связано с тем, что ASH пользуется текстами запросов, помещенных в представление pg_stat_activity, и при включенном маскировании тексты запросов в представлении находятся уже в замаскированном виде.

Специфика

Особенности маскирования запросов:

  • текст подготовленных запросов при их вызове через EXECUTE также обрабатывается по вышеуказанным правилам;
  • в случае вывода ошибки, в которой отдельно выводится лексема, которую СУБД считает ошибочной: она должна быть замаскирована по тем же правилам. То есть, если эта лексема была замаскирована в полном тексте запроса, то должна быть замаскирована и в ошибке. Исключением являются ошибки в лексемах, определяющих категорию запроса - SELECT/INSERT/UPDATE/DELETE и CREATE/ALTER ROLE/USER;
  • маскирование анонимных запросов работает в режиме полного маскирования.

Маскирование параметров функций, принимающих на вход чувствительную информацию, таких как pm_create_security_admin, pm_set_security_admin_password и add_auth_record_to_storage, будет выполняться только при значении full параметра masking_mode.

Настройка

Маскирование запросов настраивается конфигурационным параметром masking_mode (тип enum), который может принимать два значения: full или disabled.

Значение параметраОписание
disabled
Значение по умолчанию
Механизм отключен, маскирование запросов не производится, за исключением значений паролей и параметров функций, принимающих пароли, которые маскируются всегда
fullМеханизм маскирования работает по всем обрабатываемым запросам SELECT/INSERT/UPDATE/DELETE и их параметрам, а также запросам CREATE/ALTER ROLE/USER и параметру пароля в их составе.

Для применения изменения значения параметра masking_mode требуется перезагрузка сервера.

Параметр хранится в:

  • файле $PGDATA/postgresql.conf — для standalone-конфигурации;
  • файле /etc/pangolin-manager/postgres.yml — для кластерной конфигурации;
  • хранилище секретов (KMS), в параметре кластера с именем masking_mode — при защищенном конфигурировании (настроенное соединение с KMS + значение параметра secure_config = on).

Управление

При включении или отключении маскирования запросов параметр masking_mode, в случае кластерной конфигурации, следует изменить в конфигурационном файле на всех узлах кластера (Active, Standby). В противном случае при смене лидера в кластере, будут использоваться настройки лидирующего узла.

Изменение параметра требует перезагрузки сервера (restart), поскольку перечитать конфигурационные файлы — недостаточно. Изменение данного параметра в файле конфигурации не будет учитываться до перезапуска сервера. Это отражено в свойствах данного параметра: поле context=postmaster представления pg_settings.

SELECT name, context FROM pg_settings WHERE name='masking_mode';
name | context
--------------+------------
masking_mode | postmaster

Сценарии использования

Сообщения журналов

  1. Добавление параметров в хранилище паролей с помощью функции add_auth_record_to_storage.

    Пример запроса:

    SELECT add_auth_record_to_storage('<IP-адрес>', 5433, 'First_db', 'user7654', '<password>');

    add_auth_record_to_storage
    ----------------------------

    (1 row)

    Журнал сообщений:

    2023-03-02 05:50:53 MSK [15827]: [5-1] app=psql,user=postgres,db=postgres,client=<IP-адрес>,type=client backend STATEMENT:  SELECT add_auth_record_to_storage(***, ***, ***, ***, ***);

    В журнале сообщений фиксируется вывод функции add_auth_record_to_storage с аргументами, где IP-адрес, порт, имя базы данных, имя пользователя, пароль замаскированы «звездочками».

  2. Создание пользователя с использованием CREATE ROLE/USER в запросе.

    Пример запроса:

    CREATE USER user_test WITH ENCRYPTED PASSWORD '<password>';
    CREATE
    ALTER USER user_test WITH ENCRYPTED PASSWORD '<password>';
    ALTER

    Журнал сообщений:

    2023-03-02 17:50:58 MSK [30388]: [4-1] app=psql,user=postgres,db=postgres,client=<IP-адрес>,type=client backend LOG:  AUDIT: SESSION,1,1,ROLE,CREATE ROLE,,,CREATE USER user_test WITH ENCRYPTED PASSWORD ***;,<not logged>
    2023-03-02 17:51:32 MSK [30388]: [5-1] app=psql,user=postgres,db=postgres,client=<IP-адрес>,type=client backend LOG: AUDIT: SESSION,2,1,ROLE,ALTER ROLE,,,ALTER USER user_test WITH ENCRYPTED PASSWORD ***;,<not logged>

    В журнале сообщений фиксируется команда ALTER ROLE, где пароль замаскирован «звездочками».

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

    Пример запроса:

    CREATE USER user_test WITH ENCRYPTED PASSWORD '<password>';
    ERROR: role "user_test" already exists

    Журнал сообщений:

    2023-03-02 17:53:37 MSK [30388]: [6-1] app=psql,user=postgres,db=postgres,client=<IP-адрес>,type=client backend ERROR:  role "user_test" already exists
    2023-03-02 17:53:37 MSK [30388]: [7-1] app=psql,user=postgres,db=postgres,client=<IP-адрес>,type=client backend STATEMENT: CREATE USER user_test WITH ENCRYPTED PASSWORD ***;

    В журнале сообщений фиксируется команда CREATE USER, где пароль замаскирован «звездочками».

  3. Использование функции создания администратора безопасности pm_create_security_admin (при включенной защите данных от привилегированных пользователей).

    Пример запроса:

    SELECT pm_create_security_admin('sec_test1','<password>');

    pm_create_security_admin
    ----------------------------------------------------------------------------------------------------
    SCRAM-SHA-256-4096:{хеш}
    (1 row)

    Журнал сообщений:

    2022-11-18 13:23:23 MSK [18926]: [52-1] app=psql,user=sec_admin,db=postgres,client=<IP-адрес>,type=client backend LOG:  AUDIT: SESSION,14,1,READ,SELECT,,,"SELECT pm_create_security_admin('sec_test1','***');",<not logged>
    2022-11-18 13:23:23 MSK [18926]: [53-1] app=psql,user=sec_admin,db=postgres,client=<IP-адрес>,type=client backend LOG: AUDIT: SESSION,14,2,PROTECTION,EXECUTE,FUNCTION,pg_catalog.pm_create_security_admin,"SELECT pm_create_security_admin('sec_test1','***');",<not logged>
    2022-11-18 13:23:23 MSK [18926]: [54-1] app=psql,user=sec_admin,db=postgres,client=<IP-адрес>,type=client backend LOG: AUDIT: SESSION,14,3,ROLE,CREATE ROLE,,sec_test1,CREATE ROLE sec_test1 LOGIN NOINHERIT WITH VALID UNTIL 'infinity' WITH PASSWORD <REDACTED>,<not logged>
    2022-11-18 13:23:23 MSK [18926]: [55-1] app=psql,user=sec_admin,db=postgres,client=<IP-адрес>,type=client backend LOG: AUDIT: SESSION,14,4,ROLE,GRANT ROLE,,sec_test1,GRANT sec_admin_role TO sec_test1;,<not logged>
    2022-11-18 13:23:23 MSK [18926]: [56-1] app=psql,user=sec_admin,db=postgres,client=<IP-адрес>,type=client backend LOG: AUDIT: SESSION,14,5,ROLE,ALTER ROLE,,sec_test1,ALTER ROLE sec_test1 SET ROLE sec_admin_role;,<not logged>
    2022-11-18 13:23:23 MSK [18926]: [57-1] app=psql,user=sec_admin,db=postgres,client=<IP-адрес>,type=client backend LOG: AUDIT: SESSION,14,2,PROTECTION,EXECUTE,FUNCTION,pg_catalog.pm_create_security_admin,"SELECT pm_create_security_admin('sec_test1','***');",<not logged>,SUCCESS

    В журнале сообщений во всех командах SELECT пароль замаскирован «звездочками».