Maschera dati dinamica

Si applica a: SQL Server 2016 (13.x) e versioni successive del database SQL diAzure Istanzagestita di SQL di Azure Azure Synapse Analytics

Diagram of dynamic data masking.

Dynamic Data Masking (DDM) limita l'esposizione dei dati sensibili mascherandola agli utenti senza privilegi. Può essere usata per semplificare notevolmente la progettazione e la codifica della sicurezza nell'applicazione.

La maschera dati dinamica consente di impedire l'accesso non autorizzato ai dati sensibili consentendo ai clienti di specificare la quantità di dati sensibili da rivelare con un effetto 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 sono stati modificati. DDM è facile da usare con le applicazioni esistenti, poiché le regole di maschera vengono applicate 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.
  • I semplici comandi Transact-SQL definiscono e gestiscono le maschere.

Lo scopo della maschera dati dinamica è limitare l'esposizione dei dati sensibili, impedendo agli utenti che non devono avere accesso ai dati di visualizzarli. La maschera dati dinamica non mira a impedire agli utenti del database di connettersi direttamente al database ed eseguire query complete che espongono parti dei dati sensibili. La maschera dati dinamica è complementare ad altre funzionalità di sicurezza di SQL Server (controllo, crittografia, sicurezza a livello di riga e così via) ed è consigliabile usarla con loro per proteggere meglio i dati sensibili nel database.

La maschera dati dinamica è disponibile in SQL Server 2016 (13.x) e nel database SQL di Azure ed è configurata usando i 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).

Definire 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 e ora, usare (date, datetime2, datetime, datetimeoffset, smalldatetime, time). 1900-01-01 00:00:00.0000000

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()')
Indirizzo e-mail 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 year => datetime("Y")parte , month=> datetime("M") , hour=>datetime("h")day=>datetime("D"), , 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

Non è necessaria alcuna autorizzazione speciale per creare una tabella con una maschera dati dinamica, ma solo le autorizzazioni STANDARD CREATE TABLE e ALTER per lo schema.

L'aggiunta, la sostituzione o la rimozione della maschera da una colonna richiede le autorizzazioni ALTER ANY MASK e ALTER sulla tabella. È opportuno concedere ALTER ANY MASK a un responsabile della sicurezza.

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 di recuperare i dati senza maschera dalle colonne su cui è definita la maschera.

L'autorizzazione CONTROL per il database include sia l'autorizzazione ALTER ANY MASK che UNMASK che consente all'utente di visualizzare i dati non mascherati. Gli utenti amministratori o i ruoli, ad esempio sysadmin, serveradmin o db_owner dispongono dell'autorizzazione CONTROL per il database in base alla progettazione e possono visualizzare i dati non mascherati.

Nota

L'autorizzazione UNMASK non influisce sulla visibilità dei metadati: la concessione di UNMASK da sola non divulga alcun metadato. UNMASK dovrà essere sempre accompagnato da un'autorizzazione SELECT per avere qualsiasi effetto. Esempio: la concessione di UNMASK nell'ambito del database e la concessione di SELECT su una singola tabella avrà il risultato che l'utente può visualizzare solo i metadati della singola tabella da cui può 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 impedisce gli aggiornamenti a tale colonna. 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.

  • L'uso SELECT INTO di o INSERT INTO per copiare dati da una colonna mascherata in un'altra tabella comporta 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 ed esportazione di SQL Server. Un database contenente colonne mascherate genera un file di dati esportato con dati mascherati (presupponendo che venga esportato da un utente senza privilegi UNMASK ) e il database importato conterrà dati mascherati in modo statico.

Eseguire una query per le colonne mascherate

Usare la sys.masked_columns vista per eseguire una query per le colonne di tabella a cui è applicata una funzione di maschera. Questa vista eredita dalla sys.columns vista. Restituisce tutte le colonne della sys.columns vista, più le is_masked colonne e masking_function , che indicano se la colonna è mascherata e, in tal caso, quale funzione di mascheramento è definita. Questa vista mostra solo le colonne in cui è presente una funzione di maschera applicata.

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 amministratori o ruoli come sysadmin, serveradmin, db_owner e così via.

Non è possibile definire una regola di 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.

  • Non è possibile configurare una maschera in una colonna calcolata, ma se la colonna calcolata dipende da una colonna con mask, la colonna calcolata restituisce 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 l'autorizzazione UNMASK, le istruzioni READTEXT, UPDATETEXT e WRITETEXT deprecate non funzionano correttamente in una colonna configurata per Dynamic Data Masking.

L'aggiunta di una maschera dati dinamica viene implementata come modifica dello schema nella tabella sottostante e pertanto non può essere eseguita su una colonna con dipendenze. 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, stringa personalizzata casuale) 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 comportano qualsiasi tipo di confronto o operazione di join sulle colonne MASKED non fornirà risultati corretti. I risultati restituiti dal server remoto sono già in formato MASKED e non sono adatti per qualsiasi tipo di confronto o operazione di join in locale.

Nota sulla sicurezza: Ignorare il mascheramento usando tecniche di attacchi di forza bruta o inferenza

Dynamic Data Masking è progettato per semplificare lo sviluppo di applicazioni limitando l'esposizione dei dati in un set di query predefinite usate dall'applicazione. Anche se Dynamic Data Masking può essere utile anche per evitare l'esposizione accidentale dei dati sensibili quando si accede direttamente a un database di produzione, è importante notare che gli utenti senza privilegi con autorizzazioni di query ad hoc possono applicare tecniche per ottenere l'accesso ai dati effettivi. Se è necessario concedere tale accesso ad hoc, il controllo deve essere usato per monitorare tutte le attività del database e attenuare questo scenario.

Si consideri ad esempio un'entità di database con privilegi sufficienti per eseguire query ad hoc nel database e tenta di "indovinare" i dati sottostanti e infine 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 valore [Salary] di un insieme di dipendenti:

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 Dynamic Data Masking non deve essere usato come misura isolata per proteggere completamente i dati sensibili dagli utenti che eseguono query ad hoc nel database. È appropriato impedire l'esposizione accidentale dei dati sensibili, ma non protegge da finalità dannose per dedurre i dati sottostanti.

È importante gestire correttamente le autorizzazioni nel database e seguire sempre il principio minimo necessario per le autorizzazioni. 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 diversi livelli 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 utente, a un ruolo del database, a un'identità di Azure AD o a un gruppo di Azure AD. 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

Creare 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 e viene concessa l'autorizzazione SELECT per lo schema in cui risiede 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

In:

1 Rxxxxxo Tamburello xxxx RXXX@XXXX.com 91

dove il numero in DiscountCode è casuale per ogni risultato della query.

Aggiungere o modificare una maschera in 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 le autorizzazioni per visualizzare i dati non mascherati

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;

Eliminare 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 autorizzazioni granulari

  1. Creare uno schema per contenere tabelle utente:

    CREATE SCHEMA Data;
    GO
    
  2. 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
    );
    
  3. Inserire 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');
    
  4. Creare uno schema per contenere tabelle del servizio:

    CREATE SCHEMA Service;
    GO
    
  5. Creare una tabella di 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
        );
    
  6. Inserire 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');
    
  7. 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
    
  8. Concedere le 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;
    
  9. 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;
    
  10. Eseguire una query sui dati nel contesto dell'utente ServiceAttendant:

    EXECUTE AS USER = 'ServiceAttendant';
    
    SELECT MemberID, FirstName, LastName, Phone, Email, BirthDay
    FROM Data.Membership;
    
    SELECT MemberID, Feedback, Rating
    FROM Service.Feedback;
    
    REVERT;
    
  11. Eseguire una query sui dati nel contesto dell'utente ServiceLead:

    EXECUTE AS USER = 'ServiceLead';
    
    SELECT MemberID, FirstName, LastName, Phone, Email, BirthDay
    FROM Data.Membership;
    
    SELECT MemberID, Feedback, Rating
    FROM Service.Feedback;
    
    REVERT;
    
  12. Eseguire una query sui dati nel contesto dell'utente ServiceManager:

    EXECUTE AS USER = 'ServiceManager';
    
    SELECT MemberID, FirstName, LastName, Phone, Email, BirthDay
    FROM Data.Membership;
    
    SELECT MemberID, Feedback, Rating
    FROM Service.Feedback;
    
    REVERT;
    
  13. 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;
    
  14. Per revocare le 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;
    

Vedi anche