DYNAMIC DATA MASKING: примеры (SQL)
DYNAMIC_DATA_MASKING: Depends on maskОсновы Dynamic Data Masking
Dynamic Data Masking (DDM) - это функция безопасности в Microsoft SQL Server, предназначенная для ограничения раскрытия конфиденциальных данных на уровне базы данных без изменения самих данных в таблице. Она позволяет скрывать часть информации в результатах запросов для непривилегированных пользователей, в то время как данные в хранилище остаются неизменными. Эта функция применяется преимущественно для защиты персональных данных, финансовой информации или коммерческой тайны в средах разработки, тестирования или при предоставлении доступа сторонним аналитикам.
Маскирование реализуется путем определения политик маскирования на столбцах таблицы. При запросе данных пользователь с ограниченными правами видит замаскированные значения, тогда как пользователь с соответствующими разрешениями (например, с ролью UNMASK) видит исходные данные. Основные преимущества: простота внедрения, отсутствие необходимости изменять приложения и прозрачность для авторизованных пользователей.
DDM не является механизмом шифрования и не заменяет другие средства защиты, такие как прозрачное шифрование данных, Always Encrypted или управление доступом на основе ролей. Это дополнительный уровень защиты, маскирующий данные только в наборе результатов.
Аргументы и типы масок
Функция предлагает несколько встроенных типов масок, которые задаются при определении столбца или изменении его свойств:
- Default (Full masking): Полное маскирование в зависимости от типа данных. Для строковых типов возвращает XXXX (или меньше, если исходная строка короче 4 символов), для числовых - 0, для дат - 01.01.1900, для бинарных - один байт со значением 0.
- Email: Показывает первую букву адреса электронной почты, заменив остальную часть домена на константу XXX.com. Например, 'ivanov@mail.ru' превратится в 'iXXX@XXXX.com'.
- Random: Заменяет числовые значения на случайное число в заданном диапазоне. Применяется к числовым типам.
- Custom String: Позволяет определить собственный формат маскирования для строковых данных с использованием трех параметров: отображаемый префикс (сколько символов начала строки показывать), строка-заполнитель (паттерн для скрываемой части) и отображаемый суффикс (сколько символов конца строки показывать). Синтаксис: partial(prefix, padding, suffix).
Базовые примеры использования
Создание таблицы с различными типами масок при определении столбцов:
CREATE TABLE CustomerData (
ID INT PRIMARY KEY,
FullName NVARCHAR(100) MASKED WITH (FUNCTION = 'default()'),
Email NVARCHAR(100) MASKED WITH (FUNCTION = 'email()'),
PhoneNumber NVARCHAR(20) MASKED WITH (FUNCTION = 'partial(3,"****",2)'),
CreditCardNumber NVARCHAR(19) MASKED WITH (FUNCTION = 'partial(4,"XXXX-XXXX-XXXX-",4)'),
Salary DECIMAL(10,2) MASKED WITH (FUNCTION = 'random(30000, 50000)'),
BirthDate DATE MASKED WITH (FUNCTION = 'default()')
);
INSERT INTO CustomerData VALUES
(1, 'Иванов Петр Сидорович', 'ivanov@example.com', '+79161234567', '1234-5678-9012-3456', 45000.50, '1985-07-15');
-- Предоставление прав обычному пользователю
CREATE USER TestUser WITHOUT LOGIN;
GRANT SELECT ON CustomerData TO TestUser;
-- Запрос от лица пользователя без права UNMASK
EXECUTE AS USER = 'TestUser';
SELECT * FROM CustomerData;
REVERT;ID | FullName | Email | PhoneNumber | CreditCardNumber | Salary | BirthDate
----------------------------------------------------------------------------------------
1 | XXXX | iXXX@XXXX.com | +79******67 | 1234-XXXX-XXXX-3456 | 38742.15 | 1900-01-01
Добавление маски к существующему столбцу:
ALTER TABLE CustomerData
ALTER COLUMN FullName ADD MASKED WITH (FUNCTION = 'partial(1,".",2)');
-- После изменения (запрос от TestUser)
EXECUTE AS USER = 'TestUser';
SELECT FullName FROM CustomerData WHERE ID = 1;
REVERT;FullName
-----------
И..ов
Похожие технологии в MS SQL Server
Помимо Dynamic Data Masking, в SQL Server существуют другие механизмы для защиты конфиденциальных данных:
- Always Encrypted: Обеспечивает сквозное шифрование данных, при котором ключи шифрования хранятся не на сервере, а на стороне клиента. Данные остаются зашифрованными на протяжении всего времени их нахождения на сервере. Подходит для наиболее чувствительной информации. В отличие от DDM, требует изменения логики приложения.
- Row-Level Security (RLS): Позволяет ограничивать доступ к строкам таблицы на основе характеристик пользователя, выполняющего запрос. Можно скрыть целые строки, а не отдельные столбцы. Часто используется вместе с DDM для многоуровневой защиты.
- Transparent Data Encryption (TDE): Выполняет шифрование данных на уровне файлов базы данных и журналов транзакций. Защищает данные "в покое", но не маскирует их при запросах. Решает другую задачу - защиту от утечки файлов БД.
- Статическое маскирование: Реализуется с помощью специализированных инструментов или скриптов, которые навсегда изменяют данные в нерабочих средах (dev/test). DDM является динамическим и не изменяет исходные данные.
Выбор технологии зависит от сценария: DDM оптимальна для быстрого скрытия данных от непривилегированных пользователей в рабочей среде без изменения приложений. Always Encrypted - для максимальной защиты с разделением ключей. RLS - для фильтрации строк на основе роли пользователя.
Типичные ошибки и ограничения
При работе с Dynamic Data Masking могут возникнуть следующие проблемы:
- Попытка обновления данных через маскированный столбец: Пользователь без прав UNMASK не может обновлять маскированные столбцы, даже если у него есть право UPDATE.
- Некорректные параметры для маски: Указание неверных параметров для пользовательской маски partial().
- Использование в выражениях WHERE: Фильтрация по замаскированному столбцу может привести к неожиданным результатам, так как условие применяется к маскированному значению.
- Ограничения на типы данных: Не все типы данных поддерживаются для всех масок. Например, маска email применяется только к строковым типам.
- Влияние на производительность: Хотя накладные расходы минимальны, в очень высоконагруженных системах маскирование большого числа столбцов может оказывать влияние.
EXECUTE AS USER = 'TestUser';
UPDATE CustomerData SET PhoneNumber = '+79165555555' WHERE ID = 1;
REVERT;Msg 206, Level 16, State 2: Операция UPDATE запрещена для столбца "PhoneNumber", поскольку он защищен маскированием.
ALTER TABLE CustomerData
ALTER COLUMN PhoneNumber ADD MASKED WITH (FUNCTION = 'partial(10,"*",5)');
-- Ошибка, если длина PhoneNumber меньше 15 символовEXECUTE AS USER = 'TestUser';
SELECT * FROM CustomerData WHERE Email = 'ivanov@example.com';
REVERT;-- Возвращает пустой набор, так как Email в условии сравнивается с маскированным значением 'iXXX@XXXX.com'
История изменений и новые возможности
Dynamic Data MaskING была впервые представлена в SQL Server 2016 (13.x) с базовым набором функций. В последующих версиях появились улучшения:
- SQL Server 2017: Улучшена производительность и интеграция с другими компонентами безопасности.
- SQL Server 2019: Добавлена поддержка маскирования для временных таблиц и табличных переменных в ограниченном объеме. Улучшена работа с Always Encrypted.
- Azure SQL Database: Всегда получает нововведения раньше локальных версий. Например, более гибкие маски для строковых данных.
- SQL Server 2022: Расширены возможности кастомизации масок и улучшена совместимость с системами контроля доступа.
Важное изменение в последних версиях - возможность использовать маскирование в сочетании с другими функциями безопасности без конфликтов, а также более точное управление через разрешение UNMASK на уровне базы данных или схемы.
Расширенные сценарии использования
1. Комбинирование с Row-Level Security: Одновременное применение RLS для фильтрации строк и DDM для маскирования столбцов.
-- Создаем предикат безопасности для RLS
CREATE SCHEMA Security;
GO
CREATE FUNCTION Security.fn_securitypredicate(@Region AS sysname)
RETURNS TABLE
WITH SCHEMABINDING
AS RETURN SELECT 1 AS fn_securitypredicate_result
WHERE @Region = USER_NAME() OR USER_NAME() = 'Manager';
GO
CREATE SECURITY POLICY RegionPolicy
ADD FILTER PREDICATE Security.fn_securitypredicate(Region)
ON dbo.Sales,
ADD BLOCK PREDICATE Security.fn_securitypredicate(Region)
ON dbo.Sales AFTER INSERT;
-- Столбец Amount маскирован для тех, кто все же видит строку
ALTER TABLE Sales
ALTER COLUMN Amount ADD MASKED WITH (FUNCTION = 'random(1000,5000)');2. Динамическое управление маскированием через хранимые процедуры: Предоставление временного доступа к данным.
CREATE PROCEDURE ShowUnmaskedData
@TableName NVARCHAR(128),
@DurationMinutes INT = 5
AS
BEGIN
DECLARE @SQL NVARCHAR(MAX);
-- Временное предоставление права UNMASK
SET @SQL = 'GRANT UNMASK ON ' + @TableName + ' TO ' + USER_NAME();
EXEC sp_executesql @SQL;
-- Автоматический отзыв через заданное время (имитация через задание)
PRINT 'Данные будут видны без маски ' + CAST(@DurationMinutes AS NVARCHAR) + ' минут.';
END;3. Маскирование с учетом формата данных: Сложная маска для российского номера паспорта.
-- Номер паспорта: 45 01 123456 -> должно показывать 45 01 ******
ALTER TABLE Persons
ALTER COLUMN PassportNumber ADD MASKED WITH (FUNCTION = 'partial(5,"******",0)');
-- Для запроса от обычного пользователя:
-- Исходное значение: '45 01 123456'
-- Результат: '45 01 ******'4. Использование в материализованных представлениях и индексах: Маскирование сохраняется при создании представлений.
CREATE VIEW v_MaskedCustomers
AS
SELECT ID, FullName, Email, PhoneNumber
FROM CustomerData;
-- При запросе к представлению маскировка также работает
GRANT SELECT ON v_MaskedCustomers TO TestUser;5. Поэтапное внедрение маскирования в существующую систему:
-- 1. Анализ чувствительных столбцов
SELECT t.name AS TableName, c.name AS ColumnName, ty.name AS TypeName
FROM sys.columns c
JOIN sys.tables t ON c.object_id = t.object_id
JOIN sys.types ty ON c.system_type_id = ty.system_type_id
WHERE c.name LIKE '%passport%' OR c.name LIKE '%email%' OR c.name LIKE '%phone%';
-- 2. Тестирование маскирования на копии таблицы
SELECT * INTO CustomerData_Test FROM CustomerData;
ALTER TABLE CustomerData_Test
ALTER COLUMN Email ADD MASKED WITH (FUNCTION = 'email()');
-- 3. Внедрение в рабочую таблицу в период низкой нагрузки
ALTER TABLE CustomerData
ALTER COLUMN Email ADD MASKED WITH (FUNCTION = 'email()');6. Маскирование JSON данных: Работа с полями JSON-столбцов.
-- Создание таблицы с JSON
CREATE TABLE UserSettings (
UserID INT,
Settings NVARCHAR(MAX) MASKED WITH (FUNCTION = 'default()')
);
INSERT INTO UserSettings VALUES (1, '{"phone": "+79161234567", "secretKey": "AB12-CD34"}');
-- Маскирует весь JSON-текст как строку целиком
-- Альтернатива: хранение чувствительных данных в отдельных маскируемых столбцахАналоги в других СУБД
Концепция маскирования данных реализована в различных формах в других системах управления базами данных:
Oracle: Использует Virtual Private Database (VPD) и Oracle Data Redaction. Data Redaction очень похож на DDM и позволяет определять политики redaction для столбцов.
-- Oracle Data Redaction (пример)
BEGIN
DBMS_REDACT.ADD_POLICY(
object_schema => 'HR',
object_name => 'EMPLOYEES',
column_name => 'SSN',
policy_name => 'redact_emp_ssn',
function_type => DBMS_REDACT.PARTIAL,
function_parameters => 'VVVVFVVVVFVVVV,VVV-VV-,1,6'
);
END;PostgreSQL: Не имеет встроенной функции, полностью аналогичной DDM. Для похожего поведения используют представления (VIEWS) с функциями маскирования или расширения типа pg_masking. Альтернатива - создание представлений с условиями.
-- Пример через VIEW в PostgreSQL
CREATE VIEW masked_customers AS
SELECT
id,
overlay(email placing '***' from 2 for position('@' in email)-2) AS email
FROM customers;MySQL: Встроенного маскирования данных нет. Применяются пользовательские функции или маскирование на уровне приложения.
SQLite: Отсутствуют встроенные функции безопасности такого уровня. Все манипуляции с данными выполняются на уровне приложения.
IBM Db2: Имеет функцию Data Masking, которая позволяет создавать маскирующие правила для столбцов, схожую с SQL Server.
Главное отличие MS SQL DDM - глубокая интеграция с ядром СУБД и простота применения через DDL-команды без необходимости создания дополнительных объектов вроде представлений.
MS SQL DYNAMIC_DATA_MASKING function comments
- Ms SQL DYNAMIC DATA MASKING - аргументы и возвращаемое значение
- Функция sql DYNAMIC_DATA_MASKING - описание
- DYNAMIC DATA MASKING - примеры
- DYNAMIC DATA MASKING - похожие методы на sql
- DYNAMIC_DATA_MASKING на mySQL, Oracle, PostgreSQL, SQLite
- DYNAMIC DATA MASKING изменения sql
- Примеры DYNAMIC_DATA_MASKING на ms SQL