Maschera dati dinamica
Si applica a: SQL Server 2016 (13.x) e versioni successive database SQL di Azure Istanza gestita di SQL di Azure database SQL di Azure Synapse Analytics in Microsoft Fabric
La funzione Maschera dati dinamica (DDM) limita l'esposizione dei dati sensibili, nascondendoli agli utenti senza privilegi. Può essere usata per semplificare notevolmente la progettazione e la codifica della sicurezza nell'applicazione.
Questo contenuto si applica ai concetti di maschera dati dinamica in generale e specifici di SQL Server. Il contenuto specifico per altre piattaforme è disponibile:
- Per la maschera dati dinamica nel database SQL di Azure, Istanza gestita di SQL di Azure e Azure Synapse Analytics, vedere l’Introduzione alla Maschera dati dinamica del database SQL.
- Per la maschera dati dinamica in Microsoft Fabric, vedere Maschera dati dinamica nell’archiviazione dati di Fabric.
Panoramica della maschera dati dinamica
La maschera dati dinamica è utile per impedire l'accesso non autorizzato ai dati sensibili consentendo agli utenti di specificare la quantità di dati sensibili da visualizzare, con un impatto minimo sul livello dell'applicazione. È possibile configurare DDM in campi di database designati per nascondere i dati sensibili nei set di risultati delle query. Con DDM i dati nel database non vengono modificati. DDM è semplice da usare con le applicazioni esistenti, poiché vengono applicate le regole per la maschera nei risultati della query. Molte applicazioni sono in grado di mascherare i dati sensibili senza modificare le query esistenti.
- I criteri di mascheramento dei dati centrali operano direttamente sui campi sensibili del database.
- Designare gli utenti con privilegi o ruoli che hanno accesso ai dati sensibili.
- Le funzionalità DDM offrono funzioni di mascheramento completo e parziale, oltre a una maschera casuale per dati numerici.
- Semplici comandi Transact-SQL definiscono e gestiscono le maschere.
Lo scopo del Dynamic Data Masking consiste nel limitare l'esposizione dei dati sensibili, impedendo la visualizzazione dei dati agli utenti che non dovrebbero averne accesso. La maschera dati dinamica non mira a impedire agli utenti del database di connettersi direttamente al database ed eseguire query complete che espongano parti dei dati sensibili. La maschera dati dinamica è complementare ad altre funzionalità di sicurezza di SQL Server, come il controllo, la crittografia, la sicurezza a livello di riga e così via, ed è consigliabile usarla insieme per proteggere meglio i dati sensibili nel database.
La maschera dati dinamica è disponibile in SQL Server 2016 (13.x) e database SQL di Azure ed è configurata tramite comandi Transact-SQL. Per altre informazioni sulla configurazione di una maschera dati dinamica tramite il portale di Azure, vedere Maschera dati dinamica del database SQL (portale di Azure).
Nota
Microsoft Entra ID era precedentemente conosciuto come Azure Active Directory (Azure AD).
Definizione di una maschera dati dinamica
Una regola per la maschera può essere definita in una colonna all'interno di una tabella, al fine di nascondere i dati in tale colonna. Sono disponibili cinque tipi di maschere.
Funzione | Descrizione | Esempi |
---|---|---|
Default | Maschera completa in base al tipo di dati dei campi designati. Per i tipi di dati stringa, usare XXXX (o meno) se le dimensioni del campo sono inferiori a 4 caratteri (char, nchar, varchar, nvarchar, text, ntext).Per il tipo di dati numerici, usare il valore zero (bigint, bit, decimal, int, money, numeric, smallint, smallmoney, tinyint, float, real). Per i tipi di dati di data/ora, usare 1900-01-01 00:00:00.0000000 (date, datetime2, datetime, datetimeoffset, smalldatetime, time).Per i tipi di dati binati, usare un singolo byte di valore 0 ASCII (binary, varbinary, image). |
Esempio di sintassi di definizione della colonna: Phone# varchar(12) MASKED WITH (FUNCTION = 'default()') NULL Esempio di sintassi di alter: ALTER COLUMN Gender ADD MASKED WITH (FUNCTION = 'default()') |
Metodo di maschera che espone la prima lettera di un indirizzo di posta elettronica e il suffisso costante ".com", sotto forma di un indirizzo di posta elettronica. aXXX@XXXX.com . |
Esempio di sintassi di definizione: Email varchar(100) MASKED WITH (FUNCTION = 'email()') NULL Esempio di sintassi di alter: ALTER COLUMN Email ADD MASKED WITH (FUNCTION = 'email()') |
|
Casuale | Una funzione di maschera casuale per l'uso in qualsiasi tipo numerico al fine di mascherare il valore originale con un valore casuale in un intervallo specificato. | Esempio di sintassi di definizione: Account_Number bigint MASKED WITH (FUNCTION = 'random([start range], [end range])') Esempio di sintassi di alter: ALTER COLUMN [Month] ADD MASKED WITH (FUNCTION = 'random(1, 12)') |
Stringa personalizzata | Metodo di maschera che espone la prima e l'ultima lettera e aggiunge al centro una stringa di riempimento personalizzata. prefix,[padding],suffix Se il valore originale è troppo breve per completare l'intera maschera, la parte del prefisso o del suffisso non viene esposta. |
Esempio di sintassi di definizione: FirstName varchar(100) MASKED WITH (FUNCTION = 'partial(prefix,[padding],suffix)') NULL Esempio di sintassi di alter: ALTER COLUMN [Phone Number] ADD MASKED WITH (FUNCTION = 'partial(1,"XXXXXXX",0)') Questo trasforma un numero di telefono come 555.123.1234 in 5XXXXXXX . Esempio aggiuntivo: ALTER COLUMN [Phone Number] ADD MASKED WITH (FUNCTION = 'partial(5,"XXXXXXX",0)') Questo trasforma un numero di telefono come 555.123.1234 in 555.1XXXXXXX . |
Datetime | Si applica a:SQL Server 2022 (16.x) Metodo di maschera per la colonna definita con tipo di dati datetime, datetime2, date, time, datetimeoffset, smalldatetime. Consente di mascherare la parte year => datetime("Y") , month=> datetime("M") ,day=>datetime("D") , hour=>datetime("h") , minute=>datetime("m") o seconds=>datetime("s") del giorno. |
Esempio di come mascherare l'anno del valore datetime:ALTER COLUMN BirthDay ADD MASKED WITH (FUNCTION = 'datetime("Y")') Esempio di come mascherare il mese del valore datetime: ALTER COLUMN BirthDay ADD MASKED WITH (FUNCTION = 'datetime("M")') Esempio di come mascherare il minuto del valore datetime: ALTER COLUMN BirthDay ADD MASKED WITH (FUNCTION = 'datetime("m")') |
Autorizzazioni
Gli utenti con autorizzazione SELECT su una tabella possono visualizzare i dati in essa contenuti. Le colonne definite con maschera visualizzano i dati mascherati. Concedere l'autorizzazione UNMASK a un utente per consentire il recupero dei dati senza maschera dalle colonne su cui è definita la stessa maschera.
Gli utenti e ruoli amministrativi possono sempre visualizzare i dati non mascherati tramite l'autorizzazione CONTROL che include sia l’autorizzazione ALTER ANY MASK che UNMASK. Gli utenti o i ruoli amministrativi come sysadmin o db_owner dispongono, in base alla progettazione, delle autorizzazioni di CONTROLLO sul database e possono visualizzare i dati non mascherati.
Non sono necessarie autorizzazioni per creare una tabella con una maschera dati dinamica. Sono sufficienti le autorizzazioni standard per schemi CREATE TABLE e ALTER .
L'aggiunta, la sostituzione o la rimozione della maschera da una colonna richiede le autorizzazioni ALTER ANY MASK e ALTER sulla tabella. È opportuno concedere l'autorizzazione ALTER ANY MASK a un responsabile della sicurezza.
Nota
L'autorizzazione UNMASK non influisce sulla visibilità dei metadati: la sola concessione di UNMASK non divulga alcun metadato. UNMASK dovrà essere sempre accompagnato da un'autorizzazione SELECT per avere effetto. Esempio: la concessione di UNMASK nell'ambito del database e di SELECT in una singola tabella avrà il risultato che l'utente può visualizzare solo i metadati della singola tabella da cui è possibile selezionare, non altri. Vedere anche Configurazione della visibilità dei metadati.
Procedure consigliate e casi d'uso comuni
La creazione di una maschera in una colonna non ne impedisce l'aggiornamento. Pertanto, anche se gli utenti ricevono dati mascherati quando eseguono una query sulla colonna con maschera, gli stessi utenti possono aggiornare i dati se dispongono di autorizzazioni di scrittura. Tuttavia, usare un criterio di controllo di accesso appropriato per limitare le autorizzazioni all'aggiornamento.
Usando
SELECT INTO
oINSERT INTO
per copiare i dati da una colonna con maschera in un'altra tabella vengono restituiti i dati mascherati nella tabella di destinazione (presupponendo che vengano esportati da un utente senza privilegi UNMASK).La maschera dati dinamica viene applicata quando si esegue l'importazione e l'esportazione di SQL Server. Un database contenente colonne con maschera genera un file di dati esportato con dati mascherati, supponendo che venga esportato da un utente senza privilegi UNMASK, e il database importato contiene dati mascherati in modo statico.
Query per le colonne con maschera
Usare la vista sys.masked_columns
per eseguire query per tabelle e colonne con funzione di maschera applicata. Questa vista viene ereditata dalla vista sys.columns
. Questa restituisce tutte le colonne della vista sys.columns
, in aggiunta alle colonne is_masked
e masking_function
, che indicano se la colonna è nascosta e, in tal caso, quale funzione di maschera viene definita. Questa vista mostra solo le colonne su cui è applicata una funzione di maschera.
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;
Limitazioni e restrizioni
Gli utenti con CONTROL SERVER o CONTROL a livello di database possono visualizzare i dati mascherati nel formato originale. Sono inclusi utenti o ruoli amministratori come sysadmin, db_owner ecc.
Non è possibile definire una regola per la maschera per i tipi di colonna seguenti:
Colonne crittografate (Crittografia sempre attiva)
FILESTREAM
COLUMN_SET o una colonna di tipo sparse che fa parte di un set di colonne.
Una maschera non può essere configurata su una colonna calcolata, ma se la colonna calcolata dipende da una colonna dotata di MASCHERA, la colonna calcolata restituirà dati mascherati.
Una colonna con maschera dati non può essere una chiave per un indice FULLTEXT.
Colonna in una tabella esterna PolyBase.
Per gli utenti senza autorizzazione UNMASK, le istruzioni READTEXT, UPDATETEXT e WRITETEXT deprecate non funzionano correttamente in una colonna configurata per la maschera dati dinamica.
Poiché l'aggiunta di una maschera di dati dinamica viene implementata come modifica dello schema nella tabella sottostante, l'operazione non può essere eseguita in una colonna con dipendenze (ad esempio, colonna a cui fa riferimento la colonna calcolata). Il tentativo di aggiungere una maschera dati dinamica alle colonne con dipendenza genererà un errore ALTER TABLE ALTER COLUMN _columnname_ failed because one or more objects access this column
. Per aggirare questa limitazione, è possibile rimuovere la dipendenza, aggiungere la maschera di dati dinamici e quindi ricreare la dipendenza. Ad esempio, se la dipendenza è dovuta a un indice che dipende dalla colonna, è possibile eliminare l'indice, aggiungere la maschera e quindi ricreare l'indice dipendente.
Ogni volta che si proietta un'espressione che fa riferimento a una colonna per la quale viene definita una funzione di maschera dati, viene mascherata anche l'espressione. Indipendentemente dalla funzione (impostazione predefinita, posta elettronica, casuale, stringa personalizzata) usata per mascherare la colonna a cui si fa riferimento, l'espressione risultante verrà sempre mascherata con la funzione predefinita.
Le query tra database che si estendono su due database SQL di Azure o database diversi ospitati in istanze di SQL Server diverse e che comportano qualsiasi tipo di confronto od operazione di join sulle colonne MASKED, non forniscono risultati corretti. I risultati restituiti dal server remoto sono già in formato MASKED e non sono adatti per qualsiasi tipo di confronto od operazione di join in locale.
Nota
La maschera dati dinamica non è supportata quando si fa riferimento alla tabella di base sottostante in una vista indicizzata.
Nota sulla sicurezza: Ignorare il mascheramento usando tecniche di attacchi di forza bruta o inferenza
Il mascheramento dei dati dinamici è progettato per semplificare lo sviluppo di applicazioni, limitando l'esposizione dei dati in un set di query predefinito usato dall'applicazione. Nonostante possa essere utile anche per prevenire l'esposizione accidentale dei dati sensibili durante l'accesso diretto a un database di protezione, è importante notare che gli utenti senza privilegi con autorizzazioni per le query ad hoc possono applicare le tecniche per ottenere l'accesso ai dati effettivi. Se è necessario concedere l'accesso ad hoc, usare il Controllo per monitorare tutte le attività del database e attenuare questo scenario.
Ad esempio, si consideri un'entità di database con privilegi sufficienti per eseguire query ad hoc sul database che provi a trovare i dati sottostanti e infine a dedurre i valori effettivi. Si presupponga di aver definito una maschera nella colonna [Employee].[Salary]
e che l'utente si connetta direttamente al database e inizi a ipotizzare i valori, deducendo infine il [Salary]
valore nella Employees
tabella:
SELECT ID, Name, Salary FROM Employees
WHERE Salary > 99999 and Salary < 100001;
ID. Nome Salario 62543 Valeria Dal Monte 0 91245 Giorgio Cavaglieri 0
Ciò dimostra che il mascheramento dati dinamici non deve essere usato da solo come misura per garantire la sicurezza dei dati sensibili dagli utenti che eseguono query ad hoc nel database. È appropriato per impedire l'esposizione accidentale dei dati sensibili, ma non protegge da potenziali attacchi dannosi mirati a dedurre i dati sottostanti.
È importante gestire correttamente le autorizzazioni per il database e seguire sempre il principio di autorizzazioni minime necessarie. Ricordare anche di abilitare il Controllo per tenere traccia di tutte le attività eseguite sul database.
Autorizzazioni granulari introdotte in SQL Server 2022
A partire da SQL Server 2022 (16.x), è possibile impedire l'accesso non autorizzato ai dati sensibili e ottenere il controllo mascherandolo a un utente non autorizzato a livelli diversi del database. È possibile concedere o revocare l'autorizzazione UNMASK a livello di database, a livello di schema, a livello di tabella o a livello di colonna a un ruolo utente o di database, identità Microsoft Entra o gruppo Microsoft Entra. Questo miglioramento offre un modo più granulare per controllare e limitare l'accesso non autorizzato ai dati archiviati nel database e migliorare la gestione della sicurezza dei dati.
Esempi
Creazione di una maschera dati dinamica
L'esempio seguente illustra la creazione di una tabella con tre tipi diversi di maschera dati dinamica. Nell'esempio la tabella viene compilata ed è possibile selezionare la visualizzazione dei risultati.
-- 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
Viene creato un nuovo utente a cui viene concessa l’autorizzazione SELECT per lo schema in cui si trova la tabella. Le query eseguite come MaskingTestUser
possono visualizzare i dati mascherati.
CREATE USER MaskingTestUser WITHOUT LOGIN;
GRANT SELECT ON SCHEMA::Data TO MaskingTestUser;
-- impersonate for testing:
EXECUTE AS USER = 'MaskingTestUser';
SELECT * FROM Data.Membership;
REVERT;
Il risultato illustra le maschere modificando i dati da:
1 Roberto Tamburello 555.123.4567 RTamburello@contoso.com 10
a:
1 Rxxxxxo Tamburello xxxx RXXX@XXXX.com 91
dove il numero in DiscountCode
è casuale per ogni risultato della query.
Aggiunta o modifica di una maschera per una colonna esistente
Usare l'istruzione ALTER TABLE
per aggiungere una maschera a una colonna esistente nella tabella o per modificare la maschera su tale colonna.
L'esempio seguente aggiunge una funzione della maschera alla colonna LastName
:
ALTER TABLE Data.Membership
ALTER COLUMN LastName ADD MASKED WITH (FUNCTION = 'partial(2,"xxxx",0)');
L'esempio seguente modifica una funzione della maschera sulla colonna LastName
:
ALTER TABLE Data.Membership
ALTER COLUMN LastName VARCHAR(100) MASKED WITH (FUNCTION = 'default()');
Concedere autorizzazioni per visualizzare i dati senza maschera
La concessione dell'autorizzazione UNMASK consente a MaskingTestUser
di visualizzare i dati senza maschera.
GRANT UNMASK TO MaskingTestUser;
EXECUTE AS USER = 'MaskingTestUser';
SELECT * FROM Data.Membership;
REVERT;
-- Removing the UNMASK permission
REVOKE UNMASK TO MaskingTestUser;
Eliminazione di una maschera dati dinamica
L'istruzione seguente elimina la maschera della colonna LastName
creata nell'esempio precedente:
ALTER TABLE Data.Membership
ALTER COLUMN LastName DROP MASKED;
Esempi di autorizzazione granulare
Creare uno schema per contenere le tabelle utente:
CREATE SCHEMA Data; GO
Creare una tabella con colonne mascherate:
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 );
Inserisci dati di esempio:
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');
Creare uno schema per contenere le tabelle del servizio:
CREATE SCHEMA Service; GO
Creare una tabella del servizio con colonne mascherate:
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 );
Inserisci dati di esempio:
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');
Creare utenti diversi nel database:
CREATE USER ServiceAttendant WITHOUT LOGIN; GO CREATE USER ServiceLead WITHOUT LOGIN; GO CREATE USER ServiceManager WITHOUT LOGIN; GO CREATE USER ServiceHead WITHOUT LOGIN; GO
Concedere autorizzazioni di lettura agli utenti nel database:
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;
Concedere autorizzazioni UNMASK diverse agli utenti:
--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;
Eseguire query sui dati nel contesto dell'utente ServiceLead
ServiceAttendant
:EXECUTE AS USER = 'ServiceAttendant'; SELECT MemberID, FirstName, LastName, Phone, Email, BirthDay FROM Data.Membership; SELECT MemberID, Feedback, Rating FROM Service.Feedback; REVERT;
Eseguire query sui dati nel contesto dell'utente ServiceLead
ServiceLead
:EXECUTE AS USER = 'ServiceLead'; SELECT MemberID, FirstName, LastName, Phone, Email, BirthDay FROM Data.Membership; SELECT MemberID, Feedback, Rating FROM Service.Feedback; REVERT;
Eseguire query sui dati nel contesto dell'utente ServiceLead
ServiceManager
:EXECUTE AS USER = 'ServiceManager'; SELECT MemberID, FirstName, LastName, Phone, Email, BirthDay FROM Data.Membership; SELECT MemberID, Feedback, Rating FROM Service.Feedback; REVERT;
Eseguire query sui dati nel contesto dell'utente
ServiceHead
EXECUTE AS USER = 'ServiceHead'; SELECT MemberID, FirstName, LastName, Phone, Email, BirthDay FROM Data.Membership; SELECT MemberID, Feedback, Rating FROM Service.Feedback; REVERT;
Per revocare autorizzazioni UNMASK, usare le istruzioni T-SQL seguenti:
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;