Dynamisk datamaskning
gäller för: SQL Server 2016 (13.x) och senare versioner Azure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsSQL-databas i Microsoft Fabric
Dynamisk datamaskning (DDM) begränsar exponeringen av känsliga data genom att maskera den för icke-privilegierade användare. Det kan användas för att avsevärt förenkla utformningen och kodningen av säkerhet i ditt program.
Det här innehållet gäller för begrepp för dynamisk datamaskering i allmänhet och är specifikt för SQL Server. Innehåll som är specifikt för andra plattformar är tillgängligt:
- För dynamisk datamaskering i Azure SQL Database, Azure SQL Managed Instance och Azure Synapse Analytics, se Kom igång med SQL Database Dynamic Data Masking.
- Information om dynamisk datamaskering i Microsoft Fabric finns i Dynamisk datamaskning i Fabric-datalager.
Översikt över dynamisk datamaskering
Dynamisk datamaskering hjälper till att förhindra obehörig åtkomst till känsliga data genom att göra det möjligt för kunder att ange hur mycket känsliga data som ska avslöjas med minimal effekt på programskiktet. DDM kan konfigureras för avsedda databasfält för att dölja känsliga data i resultatuppsättningarna med frågor. Med DDM ändras inte data i databasen. DDM är lätt att använda med befintliga program, eftersom maskeringsregler tillämpas i frågeresultatet. Många program kan maskera känsliga data utan att ändra befintliga frågor.
- En central datamaskeringsprincip fungerar direkt på känsliga fält i databasen.
- Utse privilegierade användare eller roller som har åtkomst till känsliga data.
- DDM har funktioner för fullständig maskering och partiell maskering och en slumpmässig mask för numeriska data.
- Enkla Transact-SQL kommandon definierar och hanterar masker.
Syftet med dynamisk datamaskering är att begränsa exponeringen av känsliga data, vilket hindrar användare som inte ska ha åtkomst till data från att visa dem. Dynamisk datamaskering syftar inte till att förhindra att databasanvändare ansluter direkt till databasen och kör uttömmande frågor som exponerar delar av känsliga data. Dynamisk datamaskering kompletterar andra SQL Server-säkerhetsfunktioner (granskning, kryptering, säkerhet på radnivå osv.) och vi rekommenderar starkt att du använder den med dem för att bättre skydda känsliga data i databasen.
Dynamisk datamaskning är tillgängligt i SQL Server 2016 (13.x) och Azure SQL Database och konfigureras med hjälp av Transact-SQL kommandon. Mer information om hur du konfigurerar dynamisk datamaskering med hjälp av Azure-portalen finns i Komma igång med SQL Database Dynamic Data Masking (Azure-portalen).
Not
Microsoft Entra ID tidigare kallades Azure Active Directory (Azure AD).
Definiera en dynamisk datamaskering
En maskeringsregel kan definieras på en kolumn i en tabell för att dölja data i den kolumnen. Det finns fem typer av masker.
Funktion | Beskrivning | Exempel |
---|---|---|
Förvald | Fullständig maskering enligt datatyperna för de avsedda fälten. För strängdatatyper använder du XXXX (eller färre) om fältets storlek är mindre än 4 tecken (tecken, nchar, varchar, nvarchar, text, ntext).För numeriska datatyper använder du ett nollvärde (bigint, bit, decimal, int, money, numeric, smallint, smallmoney, tinyint, float, real). För datatyper för datum och tid använder du 1900-01-01 00:00:00.0000000 (datum, datetime2, datetime, datetimeoffset, smalldatetime, tid).För binära datatyper använder du en enda byte av ASCII-värde 0 (binary, varbinary, image). |
Exempel på kolumndefinitionssyntax: Phone# varchar(12) MASKED WITH (FUNCTION = 'default()') NULL Exempel på ändringssyntax: ALTER COLUMN Gender ADD MASKED WITH (FUNCTION = 'default()') |
E-post | Maskeringsmetod som exponerar den första bokstaven i en e-postadress och det konstanta suffixet ".com" i form av en e-postadress.
aXXX@XXXX.com . |
Exempel på definitionssyntax: Email varchar(100) MASKED WITH (FUNCTION = 'email()') NULL Exempel på ändringssyntax: ALTER COLUMN Email ADD MASKED WITH (FUNCTION = 'email()') |
Slumpmässig | En slumpmässig maskeringsfunktion för användning på valfri numerisk typ för att maskera det ursprungliga värdet med ett slumpmässigt värde inom ett angivet intervall. | Exempel på definitionssyntax: Account_Number bigint MASKED WITH (FUNCTION = 'random([start range], [end range])') Exempel på ändringssyntax: ALTER COLUMN [Month] ADD MASKED WITH (FUNCTION = 'random(1, 12)') |
Anpassad sträng | Maskeringsmetod som exponerar de första och sista bokstäverna och lägger till en anpassad utfyllnadssträng i mitten. prefix,[padding],suffix Om det ursprungliga värdet är för kort för att slutföra hela masken exponeras inte en del av prefixet eller suffixet. |
Exempel på definitionssyntax: FirstName varchar(100) MASKED WITH (FUNCTION = 'partial(prefix,[padding],suffix)') NULL Exempel på ändringssyntax: ALTER COLUMN [Phone Number] ADD MASKED WITH (FUNCTION = 'partial(1,"XXXXXXX",0)') Detta omvandlar ett telefonnummer som 555.123.1234 till 5XXXXXXX . Ytterligare exempel: ALTER COLUMN [Phone Number] ADD MASKED WITH (FUNCTION = 'partial(5,"XXXXXXX",0)') Detta omvandlar ett telefonnummer som 555.123.1234 till 555.1XXXXXXX . |
Datum och tid |
gäller för: SQL Server 2022 (16.x) Maskeringsmetod för kolumn som definierats med datatypen datetime, datetime2, date, time, datetimeoffset, smalldatetime. Det hjälper till att maskera year => datetime("Y") , month=> datetime("M") , day=>datetime("D") , hour=>datetime("h") , minute=>datetime("m") eller seconds=>datetime("s") delen av dagen. |
Exempel på hur du döljer året för datetime-värde.ALTER COLUMN BirthDay ADD MASKED WITH (FUNCTION = 'datetime("Y")') Exempel på hur du döljer månaden för datetime värde: ALTER COLUMN BirthDay ADD MASKED WITH (FUNCTION = 'datetime("M")') Exempel på hur du maskerar minutvärdet för datetime: ALTER COLUMN BirthDay ADD MASKED WITH (FUNCTION = 'datetime("m")') |
Behörigheter
Användare med SELECT- behörighet i en tabell kan visa tabelldata. Kolumner som definieras som maskerade visar maskerade data. Ge UNMASK- behörighet till en användare så att de kan hämta omaskerade data från de kolumner som maskering har definierats för.
Administrativa användare och roller kan alltid visa omaskerade data via behörigheten CONTROL, som innehåller både behörigheten ALTER ANY MASK och UNMASK. Administrativa användare eller roller som sysadmin eller db_owner har KONTROLL-behörigheter för databasen avsiktligt och kan visa omaskerade data.
Du behöver ingen särskild behörighet för att skapa en tabell med en dynamisk datamask, utan bara standard CREATE TABLE och ALTER för schemabehörigheter.
För att lägga till, ersätta eller ta bort masken för en kolumn krävs ALTER ANY MASK behörighet och ALTER behörighet i tabellen. Det är lämpligt att bevilja ALTER ANY MASK till en säkerhetsansvarig.
Not
UNMASK-behörigheten påverkar inte metadatasynlighet: om du beviljar unmask ensamt avslöjas inga metadata. UNMASK måste alltid åtföljas av en SELECT-behörighet för att ha någon effekt. Exempel: Om du beviljar UNMASK för databasomfånget och beviljar SELECT i en enskild tabell får det resultatet att användaren bara kan se metadata för den enskilda tabell som de kan välja från, inte några andra. Se även konfiguration av synlighet för metadata .
Metodtips och vanliga användningsfall
Att skapa en mask i en kolumn förhindrar inte uppdateringar av den kolumnen. Så även om användarna får maskerade data när de frågar efter den maskerade kolumnen, kan samma användare uppdatera data om de har skrivbehörighet. En korrekt åtkomstkontrollprincip bör fortfarande användas för att begränsa uppdateringsbehörigheter.
Om du använder
SELECT INTO
ellerINSERT INTO
för att kopiera data från en maskerad kolumn till en annan tabell resulterar det i maskerade data i måltabellen (förutsatt att den exporteras av en användare utan unmask privilegier).Dynamisk datamaskering tillämpas när sql server importeras och exporteras. En databas som innehåller maskerade kolumner resulterar i en exporterad datafil med maskerade data (förutsatt att den exporteras av en användare utan unmask behörigheter), och den importerade databasen innehåller statiskt maskerade data.
Fråga efter maskerade kolumner
Använd vyn sys.masked_columns
för att fråga efter tabellkolumner som har en maskeringsfunktion tillämpad på dem. Den här vyn ärver från vyn sys.columns
. Den returnerar alla kolumner i vyn sys.columns
, plus kolumnerna is_masked
och masking_function
, som anger om kolumnen är maskerad, och i så fall vilken maskeringsfunktion som definieras. Den här vyn visar bara de kolumner där en maskeringsfunktion används.
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;
Begränsningar och restriktioner
Användare med KONTROLLSERVER eller KONTROLL på databasnivå kan visa maskerade data i dess ursprungliga form. Detta omfattar administratörsanvändare eller roller som sysadmin, db_owner osv.
Det går inte att definiera en maskeringsregel för följande kolumntyper:
Krypterade kolumner ("Always Encrypted")
FILESTREAM
COLUMN_SET eller en gles kolumn som ingår i en kolumnuppsättning.
Det går inte att konfigurera en mask på en beräknad kolumn, men om den beräknade kolumnen är beroende av en kolumn med en MASK returnerar den beräknade kolumnen maskerade data.
En kolumn med datamaskering kan inte vara en nyckel för ett FULLTEXT-index.
För användare utan behörigheten UNMASK fungerar inte de inaktuella READTEXT-, UPDATETEXToch WRITETEXT--instruktioner korrekt i en kolumn som har konfigurerats för dynamisk datamaskning.
Att lägga till en dynamisk datamask implementeras som en schemaändring i den underliggande tabellen och kan därför inte utföras på en kolumn med beroenden (till exempel kolumn som refereras till av beräknad kolumn). Om du försöker lägga till dynamisk datamask mot kolumner med beroende resulterar det i ett fel, ALTER TABLE ALTER COLUMN _columnname_ failed because one or more objects access this column
. Om du vill kringgå den här begränsningen kan du först ta bort beroendet, sedan lägga till den dynamiska datamasken och sedan återskapa beroendet. Om beroendet till exempel beror på ett index som är beroende av den kolumnen kan du släppa indexet, sedan lägga till masken och sedan återskapa det beroende indexet.
När du projicerar ett uttryck som refererar till en kolumn som en datamaskeringsfunktion har definierats för, maskeras även uttrycket. Oavsett vilken funktion (standard, e-post, slumpmässig, anpassad sträng) som används för att maskera den refererade kolumnen, maskeras det resulterande uttrycket alltid med standardfunktionen.
Frågor mellan databaser som sträcker sig över två olika Azure SQL-databaser eller databaser som finns på olika SQL Server-instanser och omfattar alla typer av jämförelse- eller kopplingsåtgärder i MASKERADE kolumner ger inte rätt resultat. Resultaten som returneras från fjärrservern är redan i maskerad form och lämpar sig inte för någon typ av jämförelse eller kopplingsåtgärd lokalt.
Not
Dynamisk datamaskning stöds inte när den underliggande bastabellen refereras i en indexerad vy.
Säkerhetsanteckning: Kringgå maskering med hjälp av slutsatsdragnings- eller brute-force-tekniker
Dynamisk datamaskning är utformat för att förenkla programutvecklingen genom att begränsa dataexponeringen i en uppsättning fördefinierade frågor som används av programmet. Dynamisk datamaskering kan också vara användbart för att förhindra oavsiktlig exponering av känsliga data vid direkt åtkomst till en produktionsdatabas, men det är viktigt att observera att icke-privilegierade användare med ad hoc-frågebehörigheter kan använda tekniker för att få åtkomst till faktiska data. Om det finns ett behov av att bevilja sådan ad hoc-åtkomst bör granskning användas för att övervaka all databasaktivitet och minimera det här scenariot.
Tänk dig till exempel ett databashuvudnamn som har tillräcklig behörighet för att köra ad hoc-frågor på databasen och försöker "gissa" underliggande data och slutligen härleda de faktiska värdena. Anta att vi har en mask som definierats i kolumnen [Employee].[Salary]
och att användaren ansluter direkt till databasen genom att gissa värden, vilket till slut leder till att de kan härleda [Salary]
-värdet i tabellen Employees
.
SELECT ID, Name, Salary FROM Employees
WHERE Salary > 99999 and Salary < 100001;
Id Namn Lön 62543 Jane Doe 0 91245 John Smith 0
Detta visar att dynamisk datamaskering inte ska användas ensamt för att helt skydda känsliga data från användare som kör ad hoc-frågor i databasen. Det är lämpligt för att förhindra oavsiktlig exponering av känsliga data, men skyddar inte mot skadlig avsikt att härleda underliggande data.
Det är viktigt att hantera behörigheterna på databasen korrekt och att alltid följa principen för minimala behörigheter. Kom också ihåg att granskning är aktiverat för att spåra alla aktiviteter som äger rum i databasen.
Detaljerade behörigheter som introduceras i SQL Server 2022
Från och med SQL Server 2022 (16.x) kan du förhindra obehörig åtkomst till känsliga data och få kontroll genom att maskera dem för en obehörig användare på olika nivåer i databasen. Du kan bevilja eller återkalla UNMASK- behörighet på databasnivå, schemanivå, tabellnivå eller på kolumnnivå till en användare, databasroll, Microsoft Entra-identitet eller Microsoft Entra-grupp. Den här förbättringen ger ett mer detaljerat sätt att kontrollera och begränsa obehörig åtkomst till data som lagras i databasen och förbättra datasäkerhetshanteringen.
Exempel
Skapa en dynamisk datamask
I följande exempel skapas en tabell med tre olika typer av dynamiska datamasker. Exemplet fyller i tabellen och väljer för att visa resultatet.
-- 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
En ny användare skapas och beviljas SELECT- behörighet för schemat där tabellen finns. Frågor som körs som MaskingTestUser
visa maskerade data.
CREATE USER MaskingTestUser WITHOUT LOGIN;
GRANT SELECT ON SCHEMA::Data TO MaskingTestUser;
-- impersonate for testing:
EXECUTE AS USER = 'MaskingTestUser';
SELECT * FROM Data.Membership;
REVERT;
Resultatet visar maskerna genom att ändra data från:
1 Roberto Tamburello 555.123.4567 RTamburello@contoso.com 10
in:
1 Rxxxxxo Tamburello xxxx RXXX@XXXX.com 91
där talet i DiscountCode
är slumpmässigt för varje frågeresultat.
Lägga till eller redigera en mask i en befintlig kolumn
Använd instruktionen ALTER TABLE
för att lägga till en mask i en befintlig kolumn i tabellen eller för att redigera masken i kolumnen.
I följande exempel läggs en maskeringsfunktion till i kolumnen LastName
:
ALTER TABLE Data.Membership
ALTER COLUMN LastName ADD MASKED WITH (FUNCTION = 'partial(2,"xxxx",0)');
I följande exempel ändras en maskeringsfunktion i kolumnen LastName
:
ALTER TABLE Data.Membership
ALTER COLUMN LastName VARCHAR(100) MASKED WITH (FUNCTION = 'default()');
Bevilja behörigheter för att visa omaskerade data
Genom att bevilja behörighet UNMASK tillåter MaskingTestUser
att se data avmaskerade.
GRANT UNMASK TO MaskingTestUser;
EXECUTE AS USER = 'MaskingTestUser';
SELECT * FROM Data.Membership;
REVERT;
-- Removing the UNMASK permission
REVOKE UNMASK TO MaskingTestUser;
Avlägsna en dynamisk datamaskering
Följande instruktion släpper masken på den LastName
kolumn som skapades i föregående exempel:
ALTER TABLE Data.Membership
ALTER COLUMN LastName DROP MASKED;
Granulära behörighetsexempel
Skapa schema som ska innehålla användartabeller:
CREATE SCHEMA Data; GO
Skapa tabell med maskerade kolumner:
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 );
Infoga exempeldata:
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');
Skapa schema som ska innehålla tjänsttabeller:
CREATE SCHEMA Service; GO
Skapa tjänsttabell med maskerade kolumner:
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 );
Infoga exempeldata:
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');
Skapa olika användare i databasen:
CREATE USER ServiceAttendant WITHOUT LOGIN; GO CREATE USER ServiceLead WITHOUT LOGIN; GO CREATE USER ServiceManager WITHOUT LOGIN; GO CREATE USER ServiceHead WITHOUT LOGIN; GO
Bevilja läsbehörighet till användarna i databasen:
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;
Bevilja olika UNMASK-behörigheter till användare:
--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;
Fråga efter data i kontexten för användare
ServiceAttendant
:EXECUTE AS USER = 'ServiceAttendant'; SELECT MemberID, FirstName, LastName, Phone, Email, BirthDay FROM Data.Membership; SELECT MemberID, Feedback, Rating FROM Service.Feedback; REVERT;
Fråga efter data i kontexten för användare
ServiceLead
:EXECUTE AS USER = 'ServiceLead'; SELECT MemberID, FirstName, LastName, Phone, Email, BirthDay FROM Data.Membership; SELECT MemberID, Feedback, Rating FROM Service.Feedback; REVERT;
Fråga efter data i kontexten för användare
ServiceManager
:EXECUTE AS USER = 'ServiceManager'; SELECT MemberID, FirstName, LastName, Phone, Email, BirthDay FROM Data.Membership; SELECT MemberID, Feedback, Rating FROM Service.Feedback; REVERT;
Fråga efter data för användare
ServiceHead
EXECUTE AS USER = 'ServiceHead'; SELECT MemberID, FirstName, LastName, Phone, Email, BirthDay FROM Data.Membership; SELECT MemberID, Feedback, Rating FROM Service.Feedback; REVERT;
Om du vill återkalla UNMASK-behörigheter använder du följande T-SQL-instruktioner:
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;