Enmascaramiento de datos dinámicos

Se aplica a: SQL Server 2016 (13.x) y versiones posteriores Azure SQL DatabaseAzure SQL Managed InstanceAzure Synapse Analytics

Diagram of dynamic data masking.

El enmascaramiento dinámico de datos (DDM) limita la exposición de datos confidenciales al enmascararlo a usuarios sin privilegios. Se puede usar para simplificar considerablemente el diseño y la codificación de la seguridad en la aplicación.

El enmascaramiento dinámico de datos evita el acceso no autorizado a información confidencial al permitir que los clientes especifiquen la cantidad de información confidencial que se debe revelar, con un efecto mínimo en la capa de aplicación. DDM se puede configurar en los campos de la base de datos designada para ocultar información confidencial en los conjuntos de resultados de consultas. Con DDM no se modifican los datos en la base de datos. DDM resulta fácil de usar con las aplicaciones existentes, ya que las reglas de enmascaramiento se aplican en los resultados de la consulta. Muchas aplicaciones pueden enmascarar información confidencial sin modificar las consultas existentes.

  • Una directiva de enmascaramiento de datos central actúa directamente en los campos confidenciales de la base de datos.
  • Designe roles o usuarios con privilegios que tienen acceso a la información confidencial.
  • DDM cuenta con funciones de enmascaramiento total y parcial, además de una máscara aleatoria para datos numéricos.
  • Los comandos Transact-SQL simples definen y administran las máscaras.

La finalidad del enmascaramiento dinámico de datos es limitar la exposición de la información confidencial, impidiendo que los usuarios vean datos a los que no deberían poder acceder. El enmascaramiento dinámico de datos no pretende evitar que los usuarios de la base de datos se conecten directamente a ella y ejecuten consultas exhaustivas que expongan información confidencial. El enmascaramiento dinámico de datos es complementario de otras características de seguridad de SQL Server (auditoría, cifrado, seguridad de nivel de fila...). Es muy recomendable que se use junto a esas características para proteger mejor la información confidencial en la base de datos.

El enmascaramiento dinámico de datos está disponible en SQL Server 2016 (13.x) y en Azure SQL Database, y se configura con comandos Transact-SQL. Para obtener más información sobre cómo configurar el enmascaramiento dinámico de datos con el Portal de Azure, vea Introducción al enmascaramiento dinámico de datos de SQL Database (Portal de Azure).

Definición de una máscara de datos dinámica

Es posible definir una regla de enmascaramiento en una columna de una tabla, con el objetivo de ofuscar los datos de esa columna. Hay disponibles cinco tipos de máscaras.

Función Descripción Ejemplos
Valor predeterminado Enmascaramiento completo de acuerdo con los tipos de datos de los campos designados.

Para los tipos de datos de cadena, use XXXX (o menos) si el tamaño del campo es inferior a 4 caracteres (char, nchar, varchar, nvarchar, text, ntext).

Para los tipos de datos numéricos, use un valor cero (bigint, bit, decimal, int, money, numeric, smallint, smallmoney, tinyint, float, real).

Para los tipos de datos de fecha y hora, use (date, datetime2, datetime, datetimeoffset, smalldatetime, time). 1900-01-01 00:00:00.0000000

En lo que respecta a los tipos de datos binarios, use un solo byte de valor 0 de ASCII (binary, varbinary, image).
Ejemplo de sintaxis de definición de columna: Phone# varchar(12) MASKED WITH (FUNCTION = 'default()') NULL

Sintaxis modificada de ejemplo: ALTER COLUMN Gender ADD MASKED WITH (FUNCTION = 'default()')
Correo electrónico Método de enmascaramiento que expone la primera letra de una dirección de correo electrónico y el sufijo constante ".com", en el formato de una dirección de correo electrónico. aXXX@XXXX.com. Ejemplo de sintaxis de definición: Email varchar(100) MASKED WITH (FUNCTION = 'email()') NULL

Sintaxis modificada de ejemplo: ALTER COLUMN Email ADD MASKED WITH (FUNCTION = 'email()')
Random Una función de enmascaramiento aleatorio que se puede usar con cualquier tipo numérico a fin de enmascarar el valor original con uno aleatorio dentro de un intervalo especificado. Ejemplo de sintaxis de definición: Account_Number bigint MASKED WITH (FUNCTION = 'random([start range], [end range])')

Sintaxis modificada de ejemplo: ALTER COLUMN [Month] ADD MASKED WITH (FUNCTION = 'random(1, 12)')
Cadena personalizada Método de enmascaramiento que expone la primera y última letra y agrega una cadena de relleno personalizada en el medio. prefix,[padding],suffix

Si el valor original es demasiado corto para completar toda la máscara, no se expone parte del prefijo o sufijo.
Ejemplo de sintaxis de definición: FirstName varchar(100) MASKED WITH (FUNCTION = 'partial(prefix,[padding],suffix)') NULL

Sintaxis modificada de ejemplo: ALTER COLUMN [Phone Number] ADD MASKED WITH (FUNCTION = 'partial(1,"XXXXXXX",0)')

Esto convierte un número de teléfono como 555.123.1234 en 5XXXXXXX.

Ejemplo adicional:

ALTER COLUMN [Phone Number] ADD MASKED WITH (FUNCTION = 'partial(5,"XXXXXXX",0)')

Esto convierte un número de teléfono como 555.123.1234 en 555.1XXXXXXX.
Datetime Se aplica a: SQL Server 2022 (16.x)

Método de enmascaramiento para la columna definida con el tipo de datos datetime, datetime2, date, time, datetimeoffset, smalldatetime. Ayuda a enmascarar la parte del día year => datetime("Y"), month=> datetime("M"), day=>datetime("D"), hour=>datetime("h"), minute=>datetime("m") o la parte del día seconds=>datetime("s").
Ejemplo de cómo enmascarar el año del valor datetime :

ALTER COLUMN BirthDay ADD MASKED WITH (FUNCTION = 'datetime("Y")')

Ejemplo de cómo enmascarar el mes del valor datetime :

ALTER COLUMN BirthDay ADD MASKED WITH (FUNCTION = 'datetime("M")')

Ejemplo de cómo enmascarar el minuto del valor datetime :

ALTER COLUMN BirthDay ADD MASKED WITH (FUNCTION = 'datetime("m")')

Permisos

No se necesita ningún permiso especial para crear una tabla con una máscara dinámica de datos, solo los permisos estándar de esquema CREATE TABLE y ALTER.

Para agregar, reemplazar o quitar la máscara de una columna, se precisan los permisos ALTER ANY MASK y ALTER (este último, en la tabla). Se recomienda otorgar ALTER ANY MASK a un responsable de seguridad.

Los usuarios con el permiso SELECT en una tabla, podrán ver los datos de esta. Las columnas que estén definidas como enmascaradas mostrarán datos enmascarados. Otorgue el permiso UNMASK a un usuario para permitir que recupere datos sin enmascarar de las columnas para las que se ha definido una regla de enmascaramiento.

El permiso CONTROL de la base de datos incluye el permiso ALTER ANY MASK y UNMASK que permite al usuario ver datos sin máscara. Los usuarios administrativos o roles como sysadmin, serveradmin o db_owner tienen permiso CONTROL en la base de datos por diseño y pueden ver datos sin máscara.

Nota:

El permiso UNMASK no influye en la visibilidad de los metadatos: la concesión de UNMASK por sí sola no revela ningún metadato. Para que tenga efecto, UNMASK tendrá que ir acompañado de un permiso SELECT. Por ejemplo, si se concede UNMASK en el ámbito de la base de datos y se concede SELECT en una tabla individual, el usuario solo podrá ver los metadatos de la tabla individual en la que puede realizar una selección, no de otras. Consulte también Configuración de visibilidad de los metadatos.

Procedimientos recomendados y casos de uso habituales

  • La creación de una máscara en una columna no impide que se efectúen actualizaciones en ella. De modo que, aunque los usuarios recibirán datos enmascarados cuando realicen una consulta en una columna enmascarada, ellos mismos podrán actualizar los datos si cuentan con permisos de escritura. Aun así, se debe usar una directiva de control de acceso adecuada para limitar los permisos de actualización.

  • El uso SELECT INTO o INSERT INTO para copiar datos de una columna enmascarada en otra tabla da como resultado datos enmascarados en la tabla de destino (suponiendo que un usuario exporte sin privilegios UNMASK ).

  • El enmascaramiento dinámico de datos se aplica al ejecutar SQL Server Import and Export. Una base de datos que contiene columnas enmascaradas da como resultado un archivo de datos exportado con datos enmascarados (suponiendo que un usuario exporta sin privilegios UNMASK ) y la base de datos importada contendrá datos enmascarados estáticamente.

Consulta de columnas enmascaradas

Use la sys.masked_columns vista para consultar las columnas de tabla que tienen una función de enmascaramiento aplicada a ellas. Esta vista hereda de la sys.columns vista. Devuelve todas las columnas de la sys.columns vista, además de las is_masked columnas y masking_function , que indican si la columna está enmascarada y, si es así, qué función de enmascaramiento se define. Esta vista solo muestra las columnas en las que se ha aplicado la función de enmascaramiento.

SELECT c.name, tbl.name as table_name, c.is_masked, c.masking_function
FROM sys.masked_columns AS c
JOIN sys.tables AS tbl
    ON c.[object_id] = tbl.[object_id]
WHERE is_masked = 1;

Limitaciones y restricciones

Los usuarios con CONTROL SERVER o CONTROL en el nivel de base de datos podrían ver los datos enmascarados en su forma original. Esto incluye usuarios administradores o roles como sysadmin, serveradmin, db_owner etc.

No se puede definir una regla de enmascaramiento para los siguientes tipos de columnas:

  • Columnas cifradas (siempre cifradas)

  • FILESTREAM

  • COLUMN_SET o una columna dispersa que forme parte de un conjunto de columnas.

  • No se puede configurar una máscara en una columna calculada, pero si la columna calculada depende de una columna con una MÁSCARA, la columna calculada devuelve datos enmascarados.

  • Una columna con enmascaramiento de datos no puede ser una clave para un índice FULLTEXT.

  • Columna de una tabla externade PolyBase.

Para los usuarios sin el permiso UNMASK, las instrucciones en desuso READTEXT, UPDATETEXT y WRITETEXT no funcionan adecuadamente en una columna configurada para el enmascaramiento dinámico de datos.

Agregar una máscara dinámica de datos se implementa como un cambio de esquema en la tabla subyacente y, por lo tanto, no puede realizarse en una columna con dependencias. Para trabajar en torno a esta restricción, primero puede quitar la dependencia y, después, agregar la máscara dinámica de datos y volver a crear la dependencia. Por ejemplo, si la dependencia se debe a un índice que depende de esa columna, puede quitar el índice, después agregar la máscara y, luego, volver a crear el índice dependiente.

Cada vez que proyecta una expresión que hace referencia a una columna para la que se define una función de enmascaramiento de datos, la expresión también se enmascara. Independientemente de la función (valor predeterminado, correo electrónico, cadena aleatoria o cadena personalizada) utilizada para enmascarar la columna a la que se hace referencia, la expresión resultante siempre se enmascarará con la función predeterminada.

No proporcionarán resultados correctos las consultas cruzadas entre bases de datos que abarcan dos bases de datos Azure SQL diferentes ni bases de datos hospedadas en instancias diferentes de SQL Server y que impliquen cualquier tipo de operación de comparación o de combinación en columnas MASKED. Los resultados devueltos desde el servidor remoto ya están en formato MASKED y no son adecuados para cualquier tipo de operación de comparación o de combinación localmente.

Nota de seguridad: Omisión del enmascaramiento con técnicas de fuerza bruta o inferencia

El enmascaramiento dinámico de datos está diseñado para simplificar el desarrollo de aplicaciones limitando la exposición de datos en un conjunto de consultas predefinidas usadas por la aplicación. Aunque el enmascaramiento dinámico de datos también puede ser útil para evitar la exposición accidental de datos confidenciales al acceder directamente a una base de datos de producción, es importante tener en cuenta que los usuarios sin privilegios con permisos de consulta ad hoc pueden aplicar técnicas para obtener acceso a los datos reales. Si es necesario conceder acceso ad hoc de este tipo, la auditoría debe usarse para supervisar toda la actividad de la base de datos y mitigar este escenario.

Por ejemplo, considere una entidad de seguridad de base de datos que tenga privilegios suficientes para ejecutar consultas ad hoc en la base de datos e intente "adivinar" los datos subyacentes y, en última instancia, deducir los valores reales. Suponga que tenemos una máscara definida en la columna [Employee].[Salary] , este usuario se conecta directamente a la base de datos, comienza a adivinar los valores y, a la larga, infiere el valor [Salary] de un conjunto de empleados:

SELECT ID, Name, Salary FROM Employees
WHERE Salary > 99999 and Salary < 100001;
Id. Nombre Salario
62543 Jane Doe 0
91245 John Smith 0

Esto demuestra que el enmascaramiento dinámico de datos no debe usarse como medida aislada para proteger completamente los datos confidenciales de los usuarios que ejecutan consultas ad hoc en la base de datos. Es adecuado para evitar la exposición accidental de datos confidenciales, pero no protege contra la intención malintencionada de deducir los datos subyacentes.

Es importante administrar adecuadamente los permisos en la base de datos y seguir el principio de mínimos permisos requeridos. Además, recuerde tener habilitada la auditoría para hacer seguimiento de todas las actividades que se realizan en la base de datos.

Permisos granulares introducidos en SQL Server 2022

A partir de SQL Server 2022 (16.x), puede evitar el acceso no autorizado a datos confidenciales y obtener control enmascarando a un usuario no autorizado en distintos niveles de la base de datos. Puede conceder o revocar el permiso UNMASK en el nivel de base de datos, en el nivel de esquema, en el nivel de tabla o en el nivel de columna a un usuario, rol de base de datos, identidad de Azure AD o grupo de Azure AD. Esta mejora proporciona una manera más granular de controlar y limitar el acceso no autorizado a los datos almacenados en la base de datos, y de mejorar la administración de la seguridad de los datos.

Ejemplos

Creación de una máscara de datos dinámica

En el siguiente ejemplo se crea una tabla con tres tipos distintos de máscaras dinámicas de datos. En el ejemplo se rellena la tabla y se selecciona que se muestre el resultado.

-- schema to contain user tables
CREATE SCHEMA Data;
GO

-- table with masked columns
CREATE TABLE Data.Membership (
    MemberID INT IDENTITY(1, 1) NOT NULL PRIMARY KEY CLUSTERED,
    FirstName VARCHAR(100) MASKED WITH (FUNCTION = 'partial(1, "xxxxx", 1)') NULL,
    LastName VARCHAR(100) NOT NULL,
    Phone VARCHAR(12) MASKED WITH (FUNCTION = 'default()') NULL,
    Email VARCHAR(100) MASKED WITH (FUNCTION = 'email()') NOT NULL,
    DiscountCode SMALLINT MASKED WITH (FUNCTION = 'random(1, 100)') NULL
);

-- inserting sample data
INSERT INTO Data.Membership (FirstName, LastName, Phone, Email, DiscountCode)
VALUES
('Roberto', 'Tamburello', '555.123.4567', 'RTamburello@contoso.com', 10),
('Janice', 'Galvin', '555.123.4568', 'JGalvin@contoso.com.co', 5),
('Shakti', 'Menon', '555.123.4570', 'SMenon@contoso.net', 50),
('Zheng', 'Mu', '555.123.4569', 'ZMu@contoso.net', 40);
GO

Se crea un nuevo usuario, a quien se le otorga el permiso SELECT en el esquema donde reside la tabla. En las consultas ejecutadas como el usuario MaskingTestUser , los datos se mostrarán enmascarados.

CREATE USER MaskingTestUser WITHOUT LOGIN;

GRANT SELECT ON SCHEMA::Data TO MaskingTestUser;
  
-- impersonate for testing:
EXECUTE AS USER = 'MaskingTestUser';

SELECT * FROM Data.Membership;

REVERT;

El resultado muestra las máscaras cambiando los datos de:

1 Roberto Tamburello 555.123.4567 RTamburello@contoso.com 10

En:

1 Rxxxxxo Tamburello xxxx RXXX@XXXX.com 91

donde el número de DiscountCode es aleatorio para cada resultado de consulta.

Agregar o editar una máscara en una columna existente

Utilice la instrucción ALTER TABLE para agregar una máscara a una columna existente de la tabla o a fin de editarla en dicha columna.
En el siguiente ejemplo, se agrega la función de enmascaramiento a la columna LastName:

ALTER TABLE Data.Membership
ALTER COLUMN LastName ADD MASKED WITH (FUNCTION = 'partial(2,"xxxx",0)');

En el siguiente ejemplo se cambia la función de enmascaramiento en la columna LastName :

ALTER TABLE Data.Membership
ALTER COLUMN LastName VARCHAR(100) MASKED WITH (FUNCTION = 'default()');

Concesión de permisos para ver datos sin máscara

Si se otorga el permiso UNMASK , MaskingTestUser podrá ver los datos sin enmascarar.

GRANT UNMASK TO MaskingTestUser;

EXECUTE AS USER = 'MaskingTestUser';

SELECT * FROM Data.Membership;

REVERT;
  
-- Removing the UNMASK permission
REVOKE UNMASK TO MaskingTestUser;

Quitar una máscara de datos dinámica

La siguiente instrucción anula la máscara de la columna LastName creada en el ejemplo anterior:

ALTER TABLE Data.Membership
ALTER COLUMN LastName DROP MASKED;

Ejemplos de permiso granular

  1. Creación de un esquema que contenga tablas de usuario:

    CREATE SCHEMA Data;
    GO
    
  2. Creación de una tabla con columnas enmascaradas:

    CREATE TABLE Data.Membership (
        MemberID INT IDENTITY(1, 1) NOT NULL PRIMARY KEY CLUSTERED,
        FirstName VARCHAR(100) MASKED WITH (FUNCTION = 'partial(1, "xxxxx", 1)') NULL,
        LastName VARCHAR(100) NOT NULL,
        Phone VARCHAR(12) MASKED WITH (FUNCTION = 'default()') NULL,
        Email VARCHAR(100) MASKED WITH (FUNCTION = 'email()') NOT NULL,
        DiscountCode SMALLINT MASKED WITH (FUNCTION = 'random(1, 100)') NULL,
        BirthDay DATETIME MASKED WITH (FUNCTION = 'default()') NULL
    );
    
  3. Inserción de datos de ejemplo:

    INSERT INTO Data.Membership (FirstName, LastName, Phone, Email, DiscountCode, BirthDay)
    VALUES
    ('Roberto', 'Tamburello', '555.123.4567', 'RTamburello@contoso.com', 10, '1985-01-25 03:25:05'),
    ('Janice', 'Galvin', '555.123.4568', 'JGalvin@contoso.com.co', 5, '1990-05-14 11:30:00'),
    ('Shakti', 'Menon', '555.123.4570', 'SMenon@contoso.net', 50, '2004-02-29 14:20:10'),
    ('Zheng', 'Mu', '555.123.4569', 'ZMu@contoso.net', 40, '1990-03-01 06:00:00');
    
  4. Creación de un esquema que contenga tablas de servicio:

    CREATE SCHEMA Service;
    GO
    
  5. Creación de una tabla de servicios con columnas enmascaradas:

    CREATE TABLE Service.Feedback (
        MemberID INT IDENTITY(1, 1) NOT NULL PRIMARY KEY CLUSTERED,
        Feedback VARCHAR(100) MASKED WITH (FUNCTION = 'default()') NULL,
        Rating INT MASKED WITH (FUNCTION = 'default()'),
        Received_On DATETIME
        );
    
  6. Inserción de datos de ejemplo:

    INSERT INTO Service.Feedback(Feedback, Rating, Received_On)
    VALUES
    ('Good', 4, '2022-01-25 11:25:05'),
    ('Excellent', 5, '2021-12-22 08:10:07'),
    ('Average', 3, '2021-09-15 09:00:00');
    
  7. Creación de diferentes usuarios en la base de datos:

    CREATE USER ServiceAttendant WITHOUT LOGIN;
    GO
    
    CREATE USER ServiceLead WITHOUT LOGIN;
    GO
    
    CREATE USER ServiceManager WITHOUT LOGIN;
    GO
    
    CREATE USER ServiceHead WITHOUT LOGIN;
    GO
    
  8. Concesión de permisos de lectura a los usuarios de la base de datos:

    ALTER ROLE db_datareader ADD MEMBER ServiceAttendant;
    
    ALTER ROLE db_datareader ADD MEMBER ServiceLead;
    
    ALTER ROLE db_datareader ADD MEMBER ServiceManager;
    
    ALTER ROLE db_datareader ADD MEMBER ServiceHead;
    
  9. Concesión de diferentes permisos UNMASK a los usuarios:

    --Grant column level UNMASK permission to ServiceAttendant
    GRANT UNMASK ON Data.Membership(FirstName) TO ServiceAttendant;
    
    -- Grant table level UNMASK permission to ServiceLead
    GRANT UNMASK ON Data.Membership TO ServiceLead;
    
    -- Grant schema level UNMASK permission to ServiceManager
    GRANT UNMASK ON SCHEMA::Data TO ServiceManager;
    GRANT UNMASK ON SCHEMA::Service TO ServiceManager;
    
    --Grant database level UNMASK permission to ServiceHead;
    GRANT UNMASK TO ServiceHead;
    
  10. Consulta de los datos en el contexto del usuario ServiceAttendant:

    EXECUTE AS USER = 'ServiceAttendant';
    
    SELECT MemberID, FirstName, LastName, Phone, Email, BirthDay
    FROM Data.Membership;
    
    SELECT MemberID, Feedback, Rating
    FROM Service.Feedback;
    
    REVERT;
    
  11. Consulta de los datos en el contexto del usuario ServiceLead:

    EXECUTE AS USER = 'ServiceLead';
    
    SELECT MemberID, FirstName, LastName, Phone, Email, BirthDay
    FROM Data.Membership;
    
    SELECT MemberID, Feedback, Rating
    FROM Service.Feedback;
    
    REVERT;
    
  12. Consulta de los datos en el contexto del usuario ServiceManager:

    EXECUTE AS USER = 'ServiceManager';
    
    SELECT MemberID, FirstName, LastName, Phone, Email, BirthDay
    FROM Data.Membership;
    
    SELECT MemberID, Feedback, Rating
    FROM Service.Feedback;
    
    REVERT;
    
  13. Consulta de los datos en el contexto del usuario ServiceHead

    EXECUTE AS USER = 'ServiceHead';
    
    SELECT MemberID, FirstName, LastName, Phone, Email, BirthDay
    FROM Data.Membership;
    
    SELECT MemberID, Feedback, Rating
    FROM Service.Feedback;
    
    REVERT;
    
  14. Para revocar permisos UNMASK, use las siguientes instrucciones T-SQL:

    REVOKE UNMASK ON Data.Membership(FirstName) FROM ServiceAttendant;
    
    REVOKE UNMASK ON Data.Membership FROM ServiceLead;
    
    REVOKE UNMASK ON SCHEMA::Data FROM ServiceManager;
    
    REVOKE UNMASK ON SCHEMA::Service FROM ServiceManager;
    
    REVOKE UNMASK FROM ServiceHead;
    

Consulte también