Маскирование запросов
Описание
В СУБД 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
; - маскирование анонимных запросов работает в режиме полного маскирования;
- маскирование запросов превышающих ограничения по длине (тег окончания блока запроса не найден) также будет происходить на доступную часть строки, а система выводит предупреждение вида:
Invalid PL/PgSQL expression passed to masker, masking limited to input string only
.
Маскирование параметров функций, принимающих на вход чувствительную информацию, таких как pm_create_security_admin
, pm_set_security_admin_password
и add_auth_record_to_storage
, будет выполняться только при значении full
параметра masking_mode
.
Настройка
Маскирование запросов настраивается конфигурационным параметром masking_mode
(тип enum
), который может принимать три значения: full
, disabled
и off
.
:widths: 10 30
disabled Значение по умолчанию | Механизм отключен, маскирование запросов не производится, за исключением значений паролей и параметров функций, принимающих пароли, которые маскируются всегда |
full | Механизм маскирования работает по всем обрабатываемым запросам SELECT /INSERT /UPDATE /DELETE и их параметрам, а также запросам CREATE /ALTER ROLE /USER и параметру пароля в их составе |
off | Полное отключение механизма маскирования |
Для применения изменения значения параметра 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
Сценарии использования
Сообщения журналов
-
Добавление параметров в хранилище паролей с помощью функции
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-адрес, порт, имя базы данных, имя пользователя, пароль замаскированы «звездочками». -
Создание пользователя с использованием
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
, где пароль замаскирован «звездочками». -
Использование функции создания администратора безопасности
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
пароль замаскирован «звездочками».