Dynamické maskování dat
platí pro: SQL Server 2016 (13.x) a novější verze Azure SQL Databaseazure SQL Managed Instancedatabáze Azure Synapse AnalyticsSQL v Microsoft Fabric
Dynamické maskování dat (DDM) omezuje vystavení citlivých dat tím, že je maskuje neprivilegovaným uživatelům. Dá se použít ke zjednodušení návrhu a kódování zabezpečení ve vaší aplikaci.
Tento obsah se vztahuje na koncepty dynamického maskování dat obecně a specifické pro SQL Server. Obsah specifický pro jiné platformy je k dispozici:
- Dynamické maskování dat ve službě Azure SQL Database, Azure SQL Managed Instance a Azure Synapse Analytics najdete v tématu Začínáme s dynamickým maskováním dat služby SQL Database.
- Dynamické maskování dat v Microsoft Fabric najdete v tématu Dynamické maskování dat ve skladech dat Fabric.
Přehled dynamického maskování dat
Dynamické maskování dat pomáhá zabránit neoprávněnému přístupu k citlivým datům tím, že zákazníkům umožní určit, kolik citlivých dat se má odhalit s minimálním účinkem na aplikační vrstvu. DDM lze nakonfigurovat pro určená databázová pole tak, aby v sadách výsledků dotazů skryla citlivá data. U DDM se data v databázi nezmění. DDM se snadno používá se stávajícími aplikacemi, protože pravidla maskování se použijí ve výsledcích dotazu. Mnoho aplikací může maskovat citlivá data beze změny existujících dotazů.
- Zásady centrálního maskování dat fungují přímo na citlivá pole v databázi.
- Určete privilegované uživatele nebo role, které mají přístup k citlivým datům.
- DDM obsahuje úplné maskování a částečné maskovací funkce a náhodnou masku pro číselná data.
- Jednoduché příkazy Transact-SQL definují a spravují masky.
Účelem dynamického maskování dat je omezit vystavení citlivých dat a zabránit uživatelům, kteří by k datům neměli mít přístup. Dynamické maskování dat nemá za cíl zabránit uživatelům databáze v přímém připojení k databázi a spouštění vyčerpávajících dotazů, které zpřístupňují části citlivých dat. Dynamické maskování dat doplňuje další funkce zabezpečení SQL Serveru (auditování, šifrování, zabezpečení na úrovni řádků atd.) a důrazně se doporučuje je používat s nimi, aby bylo možné lépe chránit citlivá data v databázi.
Dynamické maskování dat je dostupné v SQL Serveru 2016 (13.x) a Azure SQL Database a je nakonfigurované pomocí příkazů Transact-SQL. Další informace o konfiguraci dynamického maskování dat pomocí webu Azure Portal najdete v tématu Začínáme s dynamickým maskováním dat služby SQL Database (Azure Portal).
Definování dynamické masky dat
Pravidlo maskování lze definovat u sloupce v tabulce, aby bylo možné obfusovat data v daném sloupci. K dispozici je pět typů masek.
Funkce | Popis | Příklady |
---|---|---|
Výchozí | Úplné maskování podle datových typů určených polí. U datových typů řetězců použijte XXXX (nebo méně), pokud je velikost pole menší než 4 znaky (znak, nchar, varchar, nvarchar, text, ntext).Pro číselné datové typy použijte nulovou hodnotu (bigint, bit, decimal, int, money, numeric, smallint, smallmoney, tinyint, float, real). U datových typů data a času použijte 1900-01-01 00:00:00.0000000 (datum, datum a čas2, datum a čas, posun data a času, malé datum a čas, čas).Pro binární datové typy použijte jeden bajt hodnoty ASCII 0 (binární, varbinární, obrázek). |
Příklad syntaxe definice sloupce: Phone# varchar(12) MASKED WITH (FUNCTION = 'default()') NULL Příklad alter syntaxe: ALTER COLUMN Gender ADD MASKED WITH (FUNCTION = 'default()') |
Metoda maskování, která zveřejňuje první písmeno e-mailové adresy a konstantní příponu ".com", ve formě e-mailové adresy.
aXXX@XXXX.com . |
Příklad syntaxe definice: Email varchar(100) MASKED WITH (FUNCTION = 'email()') NULL Příklad alter syntaxe: ALTER COLUMN Email ADD MASKED WITH (FUNCTION = 'email()') |
|
Náhodný | Funkce náhodného maskování pro použití u libovolného číselného typu k maskování původní hodnoty s náhodnou hodnotou v zadaném rozsahu. | Příklad syntaxe definice: Account_Number bigint MASKED WITH (FUNCTION = 'random([start range], [end range])') Příklad alter syntaxe: ALTER COLUMN [Month] ADD MASKED WITH (FUNCTION = 'random(1, 12)') |
Vlastní řetězec | Metoda maskování, která zveřejňuje první a poslední písmena a přidá doprostřed vlastní výplňový řetězec. prefix,[padding],suffix Pokud je původní hodnota příliš krátká k dokončení celé masky, část předpony nebo přípony není vystavena. |
Příklad syntaxe definice: FirstName varchar(100) MASKED WITH (FUNCTION = 'partial(prefix,[padding],suffix)') NULL Příklad alter syntaxe: ALTER COLUMN [Phone Number] ADD MASKED WITH (FUNCTION = 'partial(1,"XXXXXXX",0)') Tím se telefonní číslo, jako je 555.123.1234 , změní na 5XXXXXXX . Další příklad: ALTER COLUMN [Phone Number] ADD MASKED WITH (FUNCTION = 'partial(5,"XXXXXXX",0)') Tím se telefonní číslo, jako je 555.123.1234 , změní na 555.1XXXXXXX . |
Datum a čas |
platí pro: SQL Server 2022 (16.x) Metoda maskování sloupce definovaného datovým typem datetime , datetime2, datum, čas, datetimeoffset, smalldatetime. Pomáhá maskovat část dne year => datetime("Y") , month=> datetime("M") , day=>datetime("D") , hour=>datetime("h") , minute=>datetime("m") nebo seconds=>datetime("s") . |
Příklad maskování roku v hodnotě datetime :ALTER COLUMN BirthDay ADD MASKED WITH (FUNCTION = 'datetime("Y")') Příklad, jak maskovat měsíc hodnoty data a času : ALTER COLUMN BirthDay ADD MASKED WITH (FUNCTION = 'datetime("M")') Příklad, jak maskovat minutu hodnoty typu datum a čas : ALTER COLUMN BirthDay ADD MASKED WITH (FUNCTION = 'datetime("m")') |
Dovolení
Uživatelé s oprávněním SELECT v tabulce mohou zobrazit data tabulky. Sloupce definované jako maskované zobrazují maskovaná data. Udělte uživateli oprávnění UNMASK, aby mohl načíst nemaskovaná data ze sloupců, pro které je definované maskování.
Správci a role mohou vždy zobrazit nemaskovaná data prostřednictvím oprávnění CONTROL, která zahrnuje oprávnění ALTER ANY MASK i UNMASK. Administrativní uživatelé nebo role, jako jsou sysadmin nebo db_owner, mají ze zadání oprávnění CONTROL k databázi a můžou zobrazit nemaskovaná data.
K vytvoření tabulky s dynamickou maskou dat nepotřebujete žádná zvláštní oprávnění, pouze standardní CREATE TABLE a ALTER oprávnění na schéma.
Přidání, nahrazení nebo odebrání masky sloupce vyžaduje oprávnění ALTER ANY MASK a oprávnění ALTER v tabulce. Je vhodné udělit ALTER ANY MASK bezpečnostnímu důstojníkovi.
Poznámka
Oprávnění UNMASK nemá vliv na viditelnost metadat: udělení samotného oprávnění UNMASK nezpřístupňuje žádná metadata. Funkce UNMASK bude vždy muset být doprovázena oprávněním SELECT, aby se to projevilo. Příklad: Udělení funkce UNMASK pro obor databáze a udělení příkazu SELECT pro jednotlivé tabulky bude mít výsledek, že uživatel může zobrazit pouze metadata jednotlivých tabulek, ze kterých může vybrat, a ne ostatní. Viz také konfigurace viditelnosti metadat.
Osvědčené postupy a běžné případy použití
Vytvoření masky ve sloupci nebrání aktualizacím daného sloupce. I když uživatelé obdrží maskovaná data při dotazování na maskovaný sloupec, stejní uživatelé můžou data aktualizovat, pokud mají oprávnění k zápisu. K omezení oprávnění k aktualizaci by se stále měla použít správná zásada řízení přístupu.
Když použijete
SELECT INTO
neboINSERT INTO
ke kopírování dat z maskovaného sloupce do jiné tabulky, výsledkem jsou maskovaná data v cílové tabulce (za předpokladu, že je exportován uživatelem bez oprávnění unmask).Dynamické maskování dat se použije při spuštění importu a exportu SQL Serveru. Databáze obsahující maskované sloupce vede k exportovanému datovému souboru s maskovanými daty (za předpokladu, že je exportován uživatelem bez oprávnění masky UNMASK) a importovaná databáze bude obsahovat staticky maskovaná data.
Dotaz na maskované sloupce
Zobrazení sys.masked_columns
slouží k dotazování na sloupce tabulky, u kterých je použita funkce maskování. Toto zobrazení dědí ze zobrazení sys.columns
. Vrátí všechny sloupce v zobrazení sys.columns
plus sloupce is_masked
a masking_function
, které označují, jestli je sloupec maskovaný, a pokud ano, jaká maskovací funkce je definována. Toto zobrazení zobrazuje jenom sloupce, na kterých je použitá maskovací funkce.
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;
Omezení a restrikce
Uživatelé s OVLÁDACÍM SERVERem nebo CONTROL na úrovni databáze můžou zobrazit maskovaná data v původní podobě. To zahrnuje uživatele nebo role správce, jako je správce systému, db_owner atd.
Pravidlo maskování nelze definovat pro následující typy sloupců:
Šifrované sloupce (Always Encrypted)
FILESTREAM
COLUMN_SET nebo řídký sloupec, který je součástí sady sloupců.
Pro počítaný sloupec nejde nakonfigurovat masku, ale pokud vypočítaný sloupec závisí na sloupci s maskou, vrátí vypočítaný sloupec maskovaná data.
Sloupec s maskováním dat nemůže být klíčem indexu FULLTEXT.
Pro uživatele bez oprávnění UNMASK nefungují zastaralé příkazy READTEXT, UPDATETEXTa WRITETEXT správně na sloupcích nakonfigurovaných pro dynamické maskování dat.
Přidání dynamické masky dat se implementuje jako změna schématu v podkladové tabulce, a proto není možné provést u sloupce se závislostmi (například sloupec odkazovaný vypočítaným sloupcem). Při pokusu o přidání dynamické masky dat do sloupců s závislostí dojde k chybě ALTER TABLE ALTER COLUMN _columnname_ failed because one or more objects access this column
. Pokud chcete toto omezení obejít, můžete nejprve odebrat závislost, pak přidat dynamickou masku dat a pak znovu vytvořit závislost. Pokud je například závislost způsobená indexem závislým na tomto sloupci, můžete index odstranit, pak masku přidat a potom znovu vytvořit závislý index.
Kdykoli projektujete výraz odkazující na sloupec, pro který je definována funkce maskování dat, výraz se také maskuje. Bez ohledu na funkci (výchozí, e-mail, náhodný, vlastní řetězec) sloužící k maskování odkazovaného sloupce bude výsledný výraz vždy maskován s výchozí funkcí.
Dotazy napříč databázemi zahrnující dvě různé databáze Azure SQL nebo databáze hostované v různých instancích SQL Serveru a zahrnují jakoukoli operaci porovnání nebo spojení ve sloupcích MASKED neposkytují správné výsledky. Výsledky vrácené ze vzdáleného serveru jsou již ve formátu MASKED a nejsou vhodné pro žádný druh operace porovnání nebo spojení místně.
Poznámka
Dynamické maskování dat není podporováno, pokud je podkladová základní tabulka odkazována v indexovaném zobrazení.
Poznámka k zabezpečení: Obejití maskování pomocí metod odvozování nebo hrubou silou
Dynamické maskování dat je navržené tak, aby zjednodušilo vývoj aplikací omezením vystavení dat v sadě předdefinovaných dotazů používaných aplikací. Dynamické maskování dat může být užitečné také k tomu, aby se zabránilo náhodnému vystavení citlivých dat při přímém přístupu k produkční databázi, je důležité si uvědomit, že neprivilegovaní uživatelé s oprávněními k dotazům ad hoc můžou použít techniky pro získání přístupu k skutečným datům. Pokud je potřeba takový ad hoc přístup udělit, mělo by se auditování použít k monitorování všech databázových aktivit a zmírnění tohoto scénáře.
Představte si například objekt zabezpečení databáze, který má dostatečná oprávnění ke spouštění ad hoc dotazů v databázi, a snaží se uhodnout podkladová data a nakonec odvodit skutečné hodnoty. Předpokládejme, že máme masku definovanou ve sloupci [Employee].[Salary]
a tento uživatel se připojí přímo k databázi a začne odhadovat hodnoty, nakonec odvodí hodnotu [Salary]
v tabulce Employees
:
SELECT ID, Name, Salary FROM Employees
WHERE Salary > 99999 and Salary < 100001;
Id Jméno Plat 62543 Neznámá žena 0 91245 John Smith 0
To ukazuje, že dynamické maskování dat by se nemělo používat samostatně k úplnému zabezpečení citlivých dat od uživatelů, kteří spouštět ad hoc dotazy v databázi. Je vhodné zabránit náhodnému vystavení citlivých dat, ale nechrání před škodlivým záměrem odvodit podkladová data.
Je důležité správně spravovat oprávnění k databázi a vždy dodržovat minimální požadovaný princip oprávnění. Nezapomeňte také povolit auditování ke sledování všech aktivit probíhajících v databázi.
Podrobná oprávnění zavedená v SQL Serveru 2022
Počínaje SQL Serverem 2022 (16.x) můžete zabránit neoprávněnému přístupu k citlivým datům a získat kontrolu tím, že ho maskujete neoprávněnému uživateli na různých úrovních databáze. Můžete udělit nebo odvolat oprávnění UNMASK na úrovni databáze, na úrovni schématu nebo na úrovni sloupce pro uživatele, roli databáze, identitu Microsoft Entra nebo skupinu Microsoft Entra. Toto vylepšení poskytuje podrobnější způsob řízení a omezení neoprávněného přístupu k datům uloženým v databázi a zlepšení správy zabezpečení dat.
Příklady
Vytvoření dynamické masky dat
Následující příklad vytvoří tabulku se třemi různými typy dynamických masek dat. Příklad naplní tabulku a vybere výsledek.
-- 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
Vytvoří se nový uživatel a udělí SELECT oprávnění ke schématu, ve kterém se tabulka nachází. Dotazy provedené jako pohled MaskingTestUser
maskovaly 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;
Výsledek demonstruje masky tím, že mění data z:
1 Roberto Tamburello 555.123.4567 RTamburello@contoso.com 10
do:
1 Rxxxxxo Tamburello xxxx RXXX@XXXX.com 91
kde je číslo v DiscountCode
náhodné pro každý výsledek dotazu.
Přidání nebo úprava masky u existujícího sloupce
Pomocí příkazu ALTER TABLE
přidejte masku do existujícího sloupce v tabulce nebo upravte masku daného sloupce.
Následující příklad přidá funkci maskování do sloupce LastName
:
ALTER TABLE Data.Membership
ALTER COLUMN LastName ADD MASKED WITH (FUNCTION = 'partial(2,"xxxx",0)');
Následující příklad změní funkci maskování ve sloupci LastName
:
ALTER TABLE Data.Membership
ALTER COLUMN LastName VARCHAR(100) MASKED WITH (FUNCTION = 'default()');
Udělení oprávnění k zobrazení nemaskovaných dat
Udělení oprávnění
GRANT UNMASK TO MaskingTestUser;
EXECUTE AS USER = 'MaskingTestUser';
SELECT * FROM Data.Membership;
REVERT;
-- Removing the UNMASK permission
REVOKE UNMASK TO MaskingTestUser;
Odstranit dynamickou masku dat
Následující příkaz zahodí masku ve sloupci LastName
vytvořeném v předchozím příkladu:
ALTER TABLE Data.Membership
ALTER COLUMN LastName DROP MASKED;
Jemné příklady oprávnění
Vytvořte schéma, které bude obsahovat uživatelské tabulky:
CREATE SCHEMA Data; GO
Vytvoření tabulky s maskovanými sloupci:
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 );
Vložení ukázkových dat:
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');
Vytvořte schéma, které bude obsahovat tabulky služeb:
CREATE SCHEMA Service; GO
Vytvoření tabulky služby s maskovanými sloupci:
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 );
Vložení ukázkových dat:
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');
Vytvořte v databázi různé uživatele:
CREATE USER ServiceAttendant WITHOUT LOGIN; GO CREATE USER ServiceLead WITHOUT LOGIN; GO CREATE USER ServiceManager WITHOUT LOGIN; GO CREATE USER ServiceHead WITHOUT LOGIN; GO
Udělte uživatelům v databázi oprávnění ke čtení:
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;
Udělte uživatelům různá oprávnění UNMASK:
--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;
Dotaz na data v rámci kontextu uživatele
ServiceAttendant
:EXECUTE AS USER = 'ServiceAttendant'; SELECT MemberID, FirstName, LastName, Phone, Email, BirthDay FROM Data.Membership; SELECT MemberID, Feedback, Rating FROM Service.Feedback; REVERT;
Dotaz na data v rámci kontextu uživatele
ServiceLead
:EXECUTE AS USER = 'ServiceLead'; SELECT MemberID, FirstName, LastName, Phone, Email, BirthDay FROM Data.Membership; SELECT MemberID, Feedback, Rating FROM Service.Feedback; REVERT;
Dotaz na data v rámci kontextu uživatele
ServiceManager
:EXECUTE AS USER = 'ServiceManager'; SELECT MemberID, FirstName, LastName, Phone, Email, BirthDay FROM Data.Membership; SELECT MemberID, Feedback, Rating FROM Service.Feedback; REVERT;
Dotaz na data v kontextu uživatele
ServiceHead
EXECUTE AS USER = 'ServiceHead'; SELECT MemberID, FirstName, LastName, Phone, Email, BirthDay FROM Data.Membership; SELECT MemberID, Feedback, Rating FROM Service.Feedback; REVERT;
Pokud chcete odvolat oprávnění UNMASK, použijte následující příkazy 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;