Mascaramento dinâmico de dados
Aplica-se a: SQL Server 2016 (13.x) e versões posteriores Banco de Dados SQL do AzureInstância Gerenciada SQL do AzureBanco de Dados SQL do Azure Synapse Analyticsno Microsoft Fabric
O mascaramento dinâmico de dados (DDM) limita a exposição de dados confidenciais mascarando-os a usuários sem privilégios. Ele pode ser usado para simplificar muito o design e a codificação da segurança em seu aplicativo.
Esse conteúdo se aplica aos conceitos de mascaramento de dados dinâmicos em geral e específicos do SQL Server. Estão disponíveis conteúdos específicos para outras plataformas:
- Para mascaramento de dados dinâmicos no Banco de Dados SQL do Azure, na Instância Gerenciada SQL do Azure e no Azure Synapse Analytics, consulte Introdução ao Mascaramento Dinâmico de Dados do Banco de Dados SQL.
- Para mascaramento de dados dinâmicos no Microsoft Fabric, consulte Mascaramento de dados dinâmicos no armazenamento de dados do Fabric.
Visão geral do mascaramento de dados dinâmicos
O mascaramento dinâmico de dados ajuda a impedir o acesso não autorizado a dados confidenciais, permitindo que os clientes especifiquem a quantidade de dados confidenciais a serem revelados com efeito mínimo na camada de aplicativo. O DDM pode ser configurado em campos de banco de dados designados para ocultar dados confidenciais nos conjuntos de resultados de consultas. Com o DDM, os dados no banco de dados não são alterados. DDM é fácil de usar com aplicativos existentes, uma vez 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 central de mascaramento de dados atua diretamente em campos confidenciais no banco de dados.
- Designe usuários ou funções privilegiadas que tenham acesso aos dados confidenciais.
- O DDM possui funções de mascaramento completo e parcial, além de uma máscara aleatória para dados numéricos.
- Comandos Transact-SQL simples definem e gerenciam máscaras.
O objetivo do mascaramento dinâmico de dados é limitar a exposição de dados confidenciais, impedindo que usuários que não deveriam ter acesso aos dados os visualizem. O mascaramento dinâmico de dados não visa impedir que os usuários do banco de dados se conectem diretamente ao banco de dados e executem consultas exaustivas que expõem partes dos dados confidenciais. O mascaramento dinâmico de dados é complementar a outros recursos de segurança do SQL Server (auditoria, criptografia, segurança em nível de linha, etc.) e é altamente recomendável usá-lo com eles para proteger melhor os dados confidenciais no banco de dados.
O mascaramento dinâmico de dados está disponível no SQL Server 2016 (13.x) e no Banco de Dados SQL do Azure e é configurado usando comandos Transact-SQL. Para obter mais informações sobre como configurar o mascaramento de dados dinâmicos usando o portal do Azure, consulte Introdução ao mascaramento de dados dinâmicos do Banco de dados SQL (portal do Azure).
Observação
Microsoft Entra ID era anteriormente conhecido como Azure Ative Directory (Azure AD).
Definir uma máscara de dados dinâmica
Uma regra de mascaramento pode ser definida em uma coluna de uma tabela, a fim de ofuscar os dados nessa coluna. Estão disponíveis cinco tipos de máscaras.
Função | Descrição | Exemplos |
---|---|---|
Padrão | Mascaramento completo de acordo com os tipos de dados dos campos designados. Para tipos de dados de cadeia de caracteres, use XXXX (ou menos) se o tamanho do campo for inferior a 4 caracteres (char, nchar, varchar, nvarchar, text, ntext).Para tipos de dados numéricos use um valor zero (bigint, bit, decimal, int, money, numeric, smallint, smallmoney, tinyint, float, real ). Para tipos de dados de data e hora, use 1900-01-01 00:00:00.0000000 (date, datetime2, datetime, datetimeoffset, smalldatetime, time).Para tipos de dados binários, use um único byte de valor 0 no ASCII (binário, varbinary, imagem). |
Exemplo de sintaxe de definição de coluna: Phone# varchar(12) MASKED WITH (FUNCTION = 'default()') NULL Exemplo de sintaxe alternativa: ALTER COLUMN Gender ADD MASKED WITH (FUNCTION = 'default()') |
Método de mascaramento que expõe a primeira letra de um endereço de e-mail e o sufixo constante ".com", na forma de um endereço de e-mail.
aXXX@XXXX.com . |
Exemplo de sintaxe de definição: Email varchar(100) MASKED WITH (FUNCTION = 'email()') NULL Exemplo de sintaxe alternativa: 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 de sintaxe de definição: Account_Number bigint MASKED WITH (FUNCTION = 'random([start range], [end range])') Exemplo de sintaxe alternativa: ALTER COLUMN [Month] ADD MASKED WITH (FUNCTION = 'random(1, 12)') |
String personalizada | Método de mascaramento que expõe a primeira e a última letras e adiciona uma string de preenchimento personalizada entre as duas. 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 de sintaxe de definição: FirstName varchar(100) MASKED WITH (FUNCTION = 'partial(prefix,[padding],suffix)') NULL Exemplo de sintaxe alternativa: 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 . |
Data/hora |
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 year => datetime("Y") , month=> datetime("M") , day=>datetime("D") , hour=>datetime("h") , minute=>datetime("m") ou seconds=>datetime("s") parte do dia. |
Exemplo de como mascarar o ano do valor datetime :ALTER COLUMN BirthDay ADD MASKED WITH (FUNCTION = 'datetime("Y")') Exemplo de como mascarar o mês do valor de data e hora . ALTER COLUMN BirthDay ADD MASKED WITH (FUNCTION = 'datetime("M")') Exemplo de como ocultar o minuto do valor de data e hora . ALTER COLUMN BirthDay ADD MASKED WITH (FUNCTION = 'datetime("m")') |
Permissões
Os utilizadores com permissão SELECT numa tabela podem visualizar os dados da tabela. As colunas definidas como mascaradas exibem os dados mascarados. Conceda a permissão de UNMASK a um usuário para permitir que ele recupere dados não mascarados das colunas para as quais o mascaramento está definido.
Os usuários e funções administrativas sempre podem visualizar dados não mascarados por meio da permissão CONTROL, que inclui a permissão ALTER ANY MASK e UNMASK permission. Utilizadores ou funções administrativas, como sysadmin ou db_owner, têm permissões CONTROL na base de dados por design e podem visualizar dados não mascarados.
Você não precisa de nenhuma permissão especial para criar uma tabela com uma máscara de dados dinâmica, apenas o padrão CREATE TABLE e ALTER permissões de esquema.
Adicionar, substituir ou remover a máscara de uma coluna exige a permissão ALTER ANY MASK e a permissão ALTER na tabela. É adequado conceder ALTERAR QUALQUER MÁSCARA a um agente de segurança.
Observação
A permissão UNMASK não influencia a visibilidade dos metadados: conceder UNMASK por si só não divulga quaisquer metadados. A UNMASK deve ser sempre acompanhada por uma permissão SELECT para que tenha algum efeito. Exemplo: conceder UNMASK no escopo do banco de dados e conceder SELECT em uma tabela individual terá o resultado de que o usuário só pode ver os metadados da tabela individual a partir da qual ele pode selecionar, não quaisquer outros. Consulte também 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 para essa 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
ouINSERT INTO
para copiar dados de uma coluna mascarada para outra tabela resulta em dados mascarados na tabela de destino (supondo que sejam exportados por um usuário sem privilégios de UNMASK).O mascaramento dinâmico de dados é aplicado ao executar o SQL Server Import and Export. Uma base de dados contendo colunas mascaradas resulta em um ficheiro de dados exportado com dados mascarados (supondo que seja exportado por um utilizador sem privilégios de UNMASK), e a base de dados importada conterá dados estáticamente mascarados.
Consulta de colunas mascaradas
Use o modo de exibição sys.masked_columns
para consultar colunas de tabela que tenham uma função de mascaramento aplicada a elas. Esta vista herda da vista sys.columns
. Ele retorna todas as colunas na exibição sys.columns
, além das colunas is_masked
e masking_function
, indicando se a coluna está mascarada e, em caso afirmativo, qual função de mascaramento está definida. Esta vista mostra apenas as colunas nas quais existe uma função de mascaramento 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
Os usuários com CONTROL SERVER ou CONTROL no nível do banco de dados podem visualizar dados mascarados em sua forma original. Isso inclui usuários administradores ou funções como sysadmin, db_owner etc.
Não é possível definir uma regra de mascaramento para os seguintes tipos de coluna:
Colunas encriptadas (Sempre encriptadas)
FLUXO DE ARQUIVOS
COLUMN_SET ou uma coluna esparsa que faz parte de um conjunto de colunas.
Uma máscara não pode ser configurada em uma coluna computada, mas se a coluna computada depender de uma coluna com uma MÁSCARA, a coluna computada retornará dados mascarados.
Uma coluna com mascaramento de dados não pode ser uma chave para um índice FULLTEXT.
Para utilizadores sem a permissão UNMASK, as instruções preteridas READTEXT, UPDATETEXTe WRITETEXT não funcionam corretamente numa coluna configurada para mascaramento dinâmico de dados.
A adição de uma máscara de dados dinâmica é implementada como uma alteração de esquema na tabela subjacente e, portanto, não pode ser executada em uma coluna com dependências (por exemplo, coluna referenciada por coluna computada). Tentar adicionar máscara de dados dinâmicos contra colunas com dependência resultará em um erro, ALTER TABLE ALTER COLUMN _columnname_ failed because one or more objects access this column
. Para contornar essa restrição, você pode primeiro remover a dependência, em seguida, adicionar a máscara de dados dinâmicos e, em seguida, recriar a dependência. Por exemplo, se a dependência for devida a um índice dependente dessa coluna, você poderá descartar o índice, adicionar a máscara e recriar o índice dependente.
Sempre que você projeta uma expressão fazendo 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, e-mail, 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.
As consultas entre bancos de dados que abrangem dois bancos de dados SQL do Azure diferentes ou bancos de dados hospedados em instâncias diferentes do SQL Server e envolvem qualquer tipo de comparação ou operação de junção em colunas mascaradas não fornecem 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 localmente.
Observação
O mascaramento dinâmico de dados não é suportado quando a tabela base subjacente é referenciada em uma exibição indexada.
Nota de segurança: Ignorando o mascaramento usando técnicas de inferência ou força bruta
O mascaramento dinâmico de dados foi projetado para simplificar o desenvolvimento de aplicativos, limitando a exposição de dados em um conjunto de consultas predefinidas usadas pelo aplicativo. Embora o mascaramento dinâmico de dados também possa ser útil 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 obter acesso aos dados reais. Se houver necessidade de conceder esse acesso ad hoc, a Auditoria deve ser usada para monitorar toda a atividade do banco de dados e mitigar esse cenário.
Como exemplo, considere um principal de banco de dados que tenha privilégios suficientes para executar consultas ad hoc no banco de dados; tente "adivinhar" os dados subjacentes e, finalmente, inferir os valores reais. Suponha que temos uma máscara definida na coluna [Employee].[Salary]
e esse usuário se conecta diretamente ao banco de dados e começa 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 o mascaramento de dados dinâmicos não deve ser usado sozinho para proteger totalmente dados confidenciais de usuários que executam consultas ad hoc no banco de dados. É apropriado para evitar a exposição acidental de dados confidenciais, mas não protege contra a intenção maliciosa de inferir os dados subjacentes.
É importante gerenciar adequadamente as permissões no banco de dados e sempre seguir o princípio de permissões mínimas 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), você pode 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. Pode conceder ou revogar a permissão de UNMASK a nível de banco de dados, esquema, tabela ou coluna para um utilizador, função de banco de dados, identidade do Microsoft Entra ou grupo do Microsoft Entra. Esse aprimoramento fornece uma maneira mais granular de controlar e limitar o acesso não autorizado aos dados armazenados no banco de dados e melhorar o gerenciamento da segurança dos dados.
Exemplos
Criar uma máscara de dados dinâmica
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 seleciona 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 novo usuário é criado e recebe a permissão SELECT no esquema onde a tabela reside. Consultas executadas como a vista MaskingTestUser
mascararam os dados.
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 através da alteração dos dados de:
1 Roberto Tamburello 555.123.4567 RTamburello@contoso.com 10
para:
1 Rxxxxxo Tamburello xxxx RXXX@XXXX.com 91
onde o número em DiscountCode
é aleatório para cada resultado da consulta.
Adicionar ou editar uma máscara numa 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 exemplo a seguir 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 na 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
veja os dados desmascarados.
GRANT UNMASK TO MaskingTestUser;
EXECUTE AS USER = 'MaskingTestUser';
SELECT * FROM Data.Membership;
REVERT;
-- Removing the UNMASK permission
REVOKE UNMASK TO MaskingTestUser;
Remover uma máscara de dados dinâmica
A instrução a seguir descarta a máscara na coluna LastName
criada no exemplo anterior:
ALTER TABLE Data.Membership
ALTER COLUMN LastName DROP MASKED;
Exemplos de permissões granulares
Crie um esquema para conter tabelas de usuário:
CREATE SCHEMA Data; GO
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 );
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');
Crie um esquema para conter tabelas de serviço:
CREATE SCHEMA Service; GO
Crie uma 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 );
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');
Crie 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
Conceda 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;
Conceda 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;
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;
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;
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;
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;
Para revogar permissões UNMASK, use os seguintes comandos 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;