Máscara de Dados Dinâmicos

Aplica-se a: SQL Server 2016 (13.x) e versões posteriores Banco de Dados SQL do AzureInstância Gerenciada de SQL do AzureAzure Synapse Analytics

Diagram of dynamic data masking.

A DDM (Máscara Dinâmica de Dados) limita a exposição de dados confidenciais ao mascará-los para usuários não privilegiados. Ele pode ser usado para simplificar bastante o design e a codificação de segurança em seu aplicativo.

Esse conteúdo se aplica a conceitos de máscara dinâmica de dados em geral e específicos do SQL Server. Existe conteúdo disponível específico para outras plataformas:

Visão geral da máscara dinâmica de dados

O mascaramento de dados dinâmico ajuda a impedir o acesso não autorizado a dados confidenciais, permitindo que os clientes especifiquem a quantidade de dados confidenciais a revelar, com um impacto mínimo sobre a camada do aplicativo. O DDM pode ser configurado em campos de banco de dados designados para ocultar dados confidenciais nos conjuntos de resultados de consultas. Com DDM, os dados no banco de dados não são alterados. O DDM é fácil de usar com aplicativos existentes, já que as regras de mascaramento são aplicadas nos resultados da consulta. Muitos aplicativos podem mascarar dados confidenciais sem modificar consultas existentes.

  • Uma política de mascaramento de dados central atua diretamente nos campos confidenciais do banco de dados.
  • Designe usuários ou funções com privilégios que tenham acesso aos dados confidenciais.
  • O DDM apresenta funções de máscara completa e parcial e uma máscara aleatória para dados numéricos.
  • Comandos simples do Transact-SQL definem e gerenciam máscaras.

A finalidade da máscara dinâmica de dados é limitar a exposição de dados confidenciais, impedindo que os usuários que não devem ter acesso a esses dados os visualizem. A máscara dinâmica de dados não pretende impedir que usuários de banco de dados se conectem diretamente ao banco de dados e executem consultas abrangentes que exponham dados confidenciais. A máscara dinâmica de dados é complementar aos outros recursos de segurança do SQL Server (auditoria, criptografia, segurança em nível de linha etc.) e seu uso é altamente recomendável com esses outros recursos, a fim de proteger melhor os dados confidenciais no banco de dados.

A máscara dinâmica de dados está disponível em SQL Server 2016 (13.x) e Banco de Dados SQL do Azure, e é configurado usando comandos do Transact-SQL. Para obter mais informações sobre como configurar a máscara de dados dinâmicos usando o portal do Azure, veja Introdução à Máscara de Dados Dinâmicos do Banco de Dados SQL (portal do Azure).

Observação

O Microsoft Entra ID era conhecido como Azure Active Directory (Azure AD).

Definir uma máscara dinâmica de dados

Uma regra de mascaramento pode ser definida em uma coluna de uma tabela para ocultar os dados dessa coluna. Há cinco tipos de máscaras disponíveis.

Função Descrição Exemplos
Padrão Mascaramento completo de acordo com os tipos de dados dos campos designados.

Para os tipos de dados string, use XXXX ou menos se o tamanho do campo for inferior a quatro caracteres (char, nchar, varchar, nvarchar, text, ntext).

Para os tipos de dados numeric, use um valor zero (bigint, bit, decimal, int, money, numeric, smallint, smallmoney, tinyint, float, real).

Para os tipos de dados de data e hora, use 1900-01-01 00:00:00.0000000 (date, datetime2, datetime, datetimeoffset, smalldatetime, time).

Para os tipos de dados binary, use um único byte de valor ASCII 0 (binary, varbinary, image).
Exemplo da sintaxe de definição de coluna: Phone# varchar(12) MASKED WITH (FUNCTION = 'default()') NULL

Exemplo de sintaxe de alteração: ALTER COLUMN Gender ADD MASKED WITH (FUNCTION = 'default()')
Email O método de mascaramento que expõe a primeira letra de um endereço de email e o sufixo constante ".com", na forma de um endereço de email. aXXX@XXXX.com. Exemplo da sintaxe de definição: Email varchar(100) MASKED WITH (FUNCTION = 'email()') NULL

Exemplo de sintaxe de alteração: ALTER COLUMN Email ADD MASKED WITH (FUNCTION = 'email()')
Aleatório Uma função de mascaramento aleatório para uso em qualquer tipo numérico para mascarar o valor original com um valor aleatório dentro de um intervalo especificado. Exemplo da sintaxe de definição: Account_Number bigint MASKED WITH (FUNCTION = 'random([start range], [end range])')

Exemplo de sintaxe de alteração: ALTER COLUMN [Month] ADD MASKED WITH (FUNCTION = 'random(1, 12)')
Cadeia de caracteres personalizada O método de mascaramento que expõe as primeiras e últimas letras e adiciona uma cadeia de caracteres de preenchimento personalizada no meio. prefix,[padding],suffix

Se o valor original for muito curto para completar a máscara inteira, parte do prefixo ou sufixo não será exposta.
Exemplo da sintaxe de definição: FirstName varchar(100) MASKED WITH (FUNCTION = 'partial(prefix,[padding],suffix)') NULL

Exemplo de sintaxe de alteração: ALTER COLUMN [Phone Number] ADD MASKED WITH (FUNCTION = 'partial(1,"XXXXXXX",0)')

Isso transforma um número de telefone como 555.123.1234 em 5XXXXXXX.

Exemplo adicional:

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

Isso transforma um número de telefone como 555.123.1234 em 555.1XXXXXXX.
Datetime Aplica-se a: SQL Server 2022 (16.x)

Método de mascaramento para coluna definida com o tipo de dados datetime, datetime2, date, time, datetimeoffset, smalldatetime. Ajuda a mascarar a parte year => datetime("Y"), month=> datetime("M"), day=>datetime("D"), hour=>datetime("h"), minute=>datetime("m") ou seconds=>datetime("s") do dia.
Exemplo de como mascarar o ano do valor de datetime:

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

Exemplo de como mascarar o mês do valor de datetime:

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

Exemplo de como mascarar o minuto do valor de datetime:

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

Permissões

Os usuários com a permissão SELECT em uma tabela podem exibir os dados da tabela. As colunas definidas como mascaradas exibem os dados mascarados. Conceda a permissão UNMASK a um usuário para que ele possa recuperar dados não mascarados de colunas para as quais o mascaramento é definido.

Usuários e funções administrativas sempre podem exibir dados não mascarados por meio da permissão CONTROL, que inclui as permissões ALTER ANY MASK e UNMASK. Usuários ou funções administrativas, como sysadmin, serveradmin ou db_owner, têm permissões CONTROL no banco de dados por design e podem visualizar dados não mascarados.

Não é necessário qualquer permissão especial para criar uma tabela com uma máscara de dados dinâmicos, somente as permissões padrão de esquema CREATE TABLE e ALTER.

Para adicionar, substituir ou remover a máscara de uma coluna, a tabela deve ter as permissões ALTER ANY MASK e ALTER . É recomendável conceder ALTER ANY MASK para um responsável pela segurança.

Observação

A permissão UNMASK não influencia a visibilidade dos metadados: conceder UNMASK por si só não divulga metadados. A UNMASK sempre precisará ser acompanhada pela permissão SELECT para sortir algum efeito. Exemplo: conceder UNMASK no escopo do banco de dados e conceder SELECT em uma tabela individual resultará que o usuário só poderá ver os metadados da tabela individual da qual ele pode selecionar, e não quaisquer outros. Confira também a Configuração de Visibilidade de Metadados.

Práticas recomendadas e casos de uso comuns

  • Criar uma máscara em uma coluna não impede atualizações nessa coluna. Portanto, embora os usuários recebam dados mascarados ao consultar a coluna mascarada, os mesmos usuários podem atualizar os dados se tiverem permissões de gravação. Uma política de controle de acesso adequada ainda deve ser usada para limitar as permissões de atualização.

  • Usar SELECT INTO ou INSERT INTO para copiar dados de uma coluna mascarada para outra tabela resulta em dados mascarados na tabela de destino (supondo que foi exportado pelo usuário sem privilégios UNMASK).

  • A Máscara Dinâmica de Dados é aplicada durante a execução de importações e exportações do SQL Server. Um banco de dados que contém colunas mascaradas resulta em um arquivo de dados exportado contendo dados mascarados (supondo que ele seja exportado por um usuário sem privilégios de UNMASK), e o banco de dados importado conterá dados estaticamente mascarados.

Consultar colunas mascaradas

Use a exibição sys.masked_columns para consultar colunas de tabela que tenham uma função de mascaramento aplicada. Essa exibição herda valores da exibição sys.columns. Ela retorna todas as colunas na exibição sys.columns, mais as colunas is_masked e masking_function, indicando se a coluna é mascarada e, em caso positivo, qual função de mascaramento foi definida. Essa exibição só mostra colunas com uma função de máscara aplicada.

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;

Limitações e restrições

Usuários com CONTROL SERVER ou CONTROL no nível de banco de dados poderiam exibir dados mascarados na forma original. Isso inclui usuários ou funções administrativas, como sysadmin, serveradmin, db_owner etc.

Não é possível definir uma regra de mascaramento para os seguintes tipos de coluna:

  • Colunas criptografadas (Sempre Criptografadas)

  • FILESTREAM

  • COLUMN_SET ou uma coluna esparsa que faz parte de um conjunto de colunas.

  • Não é possível configurar uma máscara em uma coluna computada, mas se a coluna computada depende de uma coluna com MASK, ela retorna dados mascarados.

  • Uma coluna com mascaramento de dados não pode ser chave para um índice FULLTEXT.

  • Uma coluna em uma tabela externado PolyBase.

No caso de usuários sem a permissão UNMASK, as instruções READTEXT, UPDATETEXT e WRITETEXT preteridas não funcionarão corretamente em uma coluna configurada para Máscara Dinâmica de Dados.

A adição de uma máscara de dados dinâmicos é implementada como uma alteração de esquema na tabela subjacente e, portanto, não pode ser realizada em uma coluna com dependências. Para contornar essa restrição, você pode primeiro remover a dependência e adicionar a máscara de dados dinâmicos e, em seguida, recriar a dependência. Por exemplo, se a dependência ocorre devido a um índice dependente nessa coluna, você poderá remover o índice, adicionar a máscara e, em seguida, recriar o índice dependente.

Sempre que você projeta uma expressão que faz referência a uma coluna para a qual uma função de mascaramento de dados é definida, a expressão também é mascarada. Independentemente da função (padrão, email, aleatória, cadeia de caracteres personalizada) usada para mascarar a coluna referenciada, a expressão resultante sempre será mascarada com a função padrão.

Consultas cruzadas de bancos de dados abrangendo dois bancos de dados SQL do Azure diferentes ou bancos de dados hospedados em diferentes Instâncias do SQL Server, e envolvendo qualquer tipo de comparação ou operação de junção nas colunas MASKED, não fornecerão resultados corretos. Os resultados retornados do servidor remoto já estão no formato MASKED e não são adequados para qualquer tipo de comparação ou operação de junção local.

Observação de segurança: ignorar o mascaramento usa técnicas de inferência ou força bruta

A máscara dinâmica de dados foi desenvolvida para simplificar o desenvolvimento de aplicativos, limitando a exposição de dados em um conjunto de consultas predefinidas usadas pelo aplicativo. Embora a Máscara Dinâmica de Dados também sirva para evitar a exposição acidental de dados confidenciais ao acessar diretamente um banco de dados de produção, é importante observar que usuários sem privilégios com permissões de consulta ad hoc podem aplicar técnicas para acessar os dados reais. Se for necessário conceder esse acesso ad hoc, a auditoria deverá ser usada para monitorar todas as atividades do banco de dados e reduzir esse cenário.

Por exemplo, considere uma entidade de segurança de banco de dados que tem privilégios suficientes para executar consultas ad hoc no banco de dados e tenta “adivinhar” os dados subjacentes e inferir os valores reais. Suponha que tenhamos uma máscara definida na coluna [Employee].[Salary], e esse usuário se conecte diretamente ao banco de dados e comece a adivinhar valores, eventualmente inferindo o valor [Salary] na tabela Employees:

SELECT ID, Name, Salary FROM Employees
WHERE Salary > 99999 and Salary < 100001;
ID Nome Salário
62543 Jane Doe 0
91245 John Smith 0

Isso demonstra que a máscara dinâmica de dados não deve ser usada como medida isolada para proteger totalmente dados confidenciais de usuários que executam consultas ad hoc no banco de dados. Serve para impedir a exposição acidental de dados confidenciais, mas não protege contra intenções mal-intencionadas de inferir os dados subjacentes.

É importante gerenciar corretamente as permissões no banco de dados e sempre seguir o princípio de mínimo de permissões necessárias. Além disso, lembre-se de ter a Auditoria habilitada para acompanhar todas as atividades que ocorrem no banco de dados.

Permissões granulares introduzidas no SQL Server 2022

A partir do SQL Server 2022 (16.x), é possível impedir o acesso não autorizado a dados confidenciais e obter controle mascarando-os para um usuário não autorizado em diferentes níveis do banco de dados. Você pode conceder ou revogar a permissão UNMASK no nível do banco de dados, no nível do esquema, no nível da tabela ou no nível da coluna para um usuário, função de banco de dados, identidade do Microsoft Entra ou grupo do Microsoft Entra. Essa melhoria fornece um modo mais granular de controlar e limitar o acesso não autorizado aos dados armazenados no banco de dados, bem como aprimora o gerenciamento de segurança de dados.

Exemplos

Criar uma máscara dinâmica de dados

O exemplo a seguir cria uma tabela com três tipos diferentes de máscaras de dados dinâmicos. O exemplo preenche a tabela e faz seleções para mostrar o 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

Um usuário é criado e recebe a permissão SELECT no esquema em que a tabela reside. As consultas executadas como o MaskingTestUser exibem os dados mascarados.

CREATE USER MaskingTestUser WITHOUT LOGIN;

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

SELECT * FROM Data.Membership;

REVERT;

O resultado demonstra as máscaras ao alterar os dados de:

1 Roberto Tamburello 555.123.4567 RTamburello@contoso.com 10

para:

1 Rxxxxxo Tamburello xxxx RXXX@XXXX.com 91

em que o número em DiscountCode é aleatório para cada resultado de consulta.

Adicionar ou editar uma máscara em uma coluna existente

Use a instrução ALTER TABLE para adicionar uma máscara a uma coluna existente na tabela ou para editar a máscara nessa coluna.
O seguinte exemplo adiciona uma função de mascaramento à coluna LastName:

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

O exemplo a seguir altera uma função de mascaramento da coluna LastName :

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

Conceder permissões para exibir dados não mascarados

Conceder a permissão UNMASK permite que MaskingTestUser visualize os dados não mascarados.

GRANT UNMASK TO MaskingTestUser;

EXECUTE AS USER = 'MaskingTestUser';

SELECT * FROM Data.Membership;

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

Descartar máscara dinâmica de dados

A instrução a seguir elimina a máscara da coluna LastName criada no exemplo anterior:

ALTER TABLE Data.Membership
ALTER COLUMN LastName DROP MASKED;

Exemplos de permissão granular

  1. Criar esquema para conter tabelas de usuário:

    CREATE SCHEMA Data;
    GO
    
  2. Criar tabela com colunas mascaradas:

    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. Inserir dados de exemplo:

    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. Criar esquema para conter tabelas de serviço:

    CREATE SCHEMA Service;
    GO
    
  5. Criar tabela de serviço com colunas mascaradas:

    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. Inserir dados de exemplo:

    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. Criar usuários diferentes no banco de dados:

    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. Conceder permissões de leitura aos usuários no banco de dados:

    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. Conceder diferentes permissões UNMASK aos usuários:

    --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. Consultar os dados no contexto do usuário ServiceAttendant:

    EXECUTE AS USER = 'ServiceAttendant';
    
    SELECT MemberID, FirstName, LastName, Phone, Email, BirthDay
    FROM Data.Membership;
    
    SELECT MemberID, Feedback, Rating
    FROM Service.Feedback;
    
    REVERT;
    
  11. Consultar os dados no contexto do usuário ServiceLead:

    EXECUTE AS USER = 'ServiceLead';
    
    SELECT MemberID, FirstName, LastName, Phone, Email, BirthDay
    FROM Data.Membership;
    
    SELECT MemberID, Feedback, Rating
    FROM Service.Feedback;
    
    REVERT;
    
  12. Consultar os dados no contexto do usuário ServiceManager:

    EXECUTE AS USER = 'ServiceManager';
    
    SELECT MemberID, FirstName, LastName, Phone, Email, BirthDay
    FROM Data.Membership;
    
    SELECT MemberID, Feedback, Rating
    FROM Service.Feedback;
    
    REVERT;
    
  13. Consultar os dados no contexto do usuário 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 revogar permissões UNMASK, use as seguintes instruções 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;