Penyelubungan data dinamis

Berlaku untuk: SQL Server 2016 (13.x) dan yang lebih baru Azure SQL DatabaseAzure SQL Managed InstanceAzure Synapse Analytics

Diagram masking data dinamis.

Masking data dinamis (DDM) membatasi paparan data sensitif dengan menutupinya kepada pengguna yang tidak memiliki hak istimewa. Ia dapat digunakan untuk menyederhanakan desain dan pengodean keamanan dalam aplikasi Anda.

Konten ini berlaku untuk konsep masking data dinamis umumnya, dan khusus untuk SQL Server. Konten khusus untuk platform lain tersedia:

Gambaran umum masking data dinamis

Masking data dinamis membantu mencegah akses tidak sah ke data sensitif dengan memungkinkan pelanggan menentukan berapa banyak data sensitif untuk diungkapkan dengan efek minimal pada lapisan aplikasi. DDM dapat dikonfigurasi pada bidang database yang ditunjuk untuk menyembunyikan data sensitif dalam kumpulan hasil kueri. Dengan DDM, data dalam database tidak diubah. DDM mudah digunakan dengan aplikasi yang ada, karena aturan masking diterapkan dalam hasil kueri. Banyak aplikasi dapat menutupi data sensitif tanpa memodifikasi kueri yang ada.

  • Kebijakan masking data pusat bertindak langsung pada bidang sensitif dalam database.
  • Menunjuk pengguna atau peran istimewa yang memang memiliki akses ke data sensitif.
  • DDM memiliki fungsi masking penuh dan masking parsial, dan masker acak untuk data numerik.
  • Perintah Transact-SQL sederhana menentukan dan mengelola masker.

Tujuan masking data dinamis adalah untuk membatasi paparan data sensitif, mencegah pengguna yang seharusnya tidak memiliki akses ke data untuk melihatnya. Masking data dinamis tidak bertujuan untuk mencegah pengguna database terhubung langsung ke database dan menjalankan kueri lengkap yang mengekspos potongan data sensitif. Masking data dinamis melengkapi fitur keamanan SQL Server lainnya (audit, enkripsi, keamanan tingkat baris, dll.) dan sangat disarankan untuk menggunakannya dengan mereka untuk melindungi data sensitif dalam database dengan lebih baik.

Masking data dinamis tersedia di SQL Server 2016 (13.x) dan Azure SQL Database, dan dikonfigurasi dengan menggunakan perintah Transact-SQL. Untuk informasi selengkapnya tentang mengonfigurasi masking data dinamis dengan menggunakan portal Azure, lihat Mulai menggunakan Masking Data Dinamis SQL Database (portal Azure).

Catatan

ID Microsoft Entra sebelumnya dikenal sebagai Azure Active Directory (Azure AD).

Menentukan masker data dinamis

Aturan masking dapat ditentukan pada kolom dalam tabel, untuk mengaburkan data di kolom tersebut. Tersedia lima jenis masker.

Fungsi Deskripsi Contoh
Default Masking penuh sesuai dengan jenis data bidang yang ditunjuk.

Untuk jenis data string, gunakan XXXX (atau kurang) jika ukuran bidang kurang dari 4 karakter (karakter, nchar, varchar, nvarchar, teks, ntext).

Untuk jenis data numerik, gunakan nilai nol (bigint, bit, desimal, int, uang, numerik, smallint, smallmoney, tinyint, float, real).

Untuk jenis data tanggal dan waktu, gunakan 1900-01-01 00:00:00.0000000 (tanggal, tanggalwaktu2, tanggalwaktu, datetimeoffset, smalldatetime, waktu).

Untuk jenis data biner, gunakan satu byte nilai ASCII 0 (biner, varbinary, image).
Contoh sintaks definisi kolom: Phone# varchar(12) MASKED WITH (FUNCTION = 'default()') NULL

Contoh sintaksis perubahan: ALTER COLUMN Gender ADD MASKED WITH (FUNCTION = 'default()')
Email Metode masking yang mengekspos huruf pertama alamat email dan akhiran konstan ".com", dalam bentuk alamat email. aXXX@XXXX.com. Contoh sintaks definisi: Email varchar(100) MASKED WITH (FUNCTION = 'email()') NULL

Contoh sintaksis perubahan: ALTER COLUMN Email ADD MASKED WITH (FUNCTION = 'email()')
Acak Fungsi masking acak untuk digunakan pada jenis numerik apa pun untuk menutupi nilai asli dengan nilai acak dalam rentang tertentu. Contoh sintaks definisi: Account_Number bigint MASKED WITH (FUNCTION = 'random([start range], [end range])')

Contoh sintaksis perubahan: ALTER COLUMN [Month] ADD MASKED WITH (FUNCTION = 'random(1, 12)')
String Kustom Metode masking yang mengekspos huruf pertama dan terakhir dan menambahkan string padding kustom di tengah. prefix,[padding],suffix

Jika nilai asli terlalu pendek untuk menyelesaikan seluruh masker, bagian dari awalan atau akhiran tidak terekspos.
Contoh sintaks definisi: FirstName varchar(100) MASKED WITH (FUNCTION = 'partial(prefix,[padding],suffix)') NULL

Contoh sintaksis perubahan: ALTER COLUMN [Phone Number] ADD MASKED WITH (FUNCTION = 'partial(1,"XXXXXXX",0)')

Ini mengubah nomor telepon seperti 555.123.1234 menjadi 5XXXXXXX.

Contoh tambahan:

ALTER COLUMN [Phone Number] ADD MASKED WITH (FUNCTION = 'partial(5,"XXXXXXX",0)')

Ini mengubah nomor telepon seperti 555.123.1234 menjadi 555.1XXXXXXX.
Tanggalwaktu Berlaku untuk: SQL Server 2022 (16.x)

Metode masking untuk kolom yang ditentukan dengan jenis data datetime, datetime2, date, time, datetimeoffset, smalldatetime. Ini membantu menutupi year => datetime("Y")bagian , , month=> datetime("M")day=>datetime("D"), hour=>datetime("h"), minute=>datetime("m"), atau seconds=>datetime("s") hari itu.
Contoh cara menutupi tahun nilai tanggalwaktu :

ALTER COLUMN BirthDay ADD MASKED WITH (FUNCTION = 'datetime("Y")')

Contoh cara menutupi bulan nilai tanggalwaktu :

ALTER COLUMN BirthDay ADD MASKED WITH (FUNCTION = 'datetime("M")')

Contoh cara menutupi menit dari nilai tanggalwaktu :

ALTER COLUMN BirthDay ADD MASKED WITH (FUNCTION = 'datetime("m")')

Izin

Pengguna dengan izin SELECT pada tabel dapat menampilkan data tabel. Kolom yang ditetapkan sebagai tersembunyi akan menampilkan data yang disembunyikan. Berikan izin UNMASK kepada pengguna untuk memungkinkan mereka mengambil data yang tidak dimasak dari kolom yang maskingnya ditentukan.

Pengguna dan peran administratif selalu dapat melihat data yang tidak dimasak melalui izin CONTROL , yang mencakup izin UBAH MASKER DAN UNMASK . Pengguna atau peran administratif seperti sysadmin, serveradmin, atau db_owner memiliki izin CONTROL pada database berdasarkan desain, dan dapat melihat data yang tidak dimasak.

Anda tidak memerlukan izin khusus untuk membuat tabel dengan masker data dinamis, hanya CREATE TABLE standar dan UBAH pada izin skema.

Menambahkan, mengganti, atau menghapus masker kolom membutuhkan izin UBAH MASKING dan UBAH pada tabel. Sangat tepat untuk memberikan ALTER ANY MASK kepada petugas keamanan.

Catatan

Izin UNMASK tidak memengaruhi visibilitas metadata: memberikan UNMASK saja tidak mengungkapkan metadata apa pun. UNMASK akan selalu perlu disertai dengan izin SELECT untuk memiliki efek apa pun. Contoh: memberikan UNMASK pada cakupan database dan memberikan SELECT pada Tabel individual akan memiliki hasil bahwa pengguna hanya dapat melihat metadata tabel individual tempat dia dapat memilih, bukan yang lain. Lihat juga Konfigurasi Visibilitas Metadata.

Praktik terbaik dan kasus penggunaan umum

  • Membuat masker pada kolom tidak mencegah pembaruan pada kolom tersebut. Jadi, meskipun pengguna menerima data bertopeng saat mengkueri kolom bertopeng, pengguna yang sama dapat memperbarui data jika mereka memiliki izin tulis. Kebijakan kontrol akses yang tepat masih harus digunakan untuk membatasi izin pembaruan.

  • Menggunakan SELECT INTO atau INSERT INTO untuk menyalin data dari kolom bertopeng ke tabel lain menghasilkan data yang ditutupi dalam tabel target (dengan asumsi data diekspor oleh pengguna tanpa hak istimewa UNMASK ).

  • Masking Data Dinamis diterapkan saat menjalankan Impor dan Ekspor SQL Server. Database yang berisi kolom bertopeng menghasilkan file data yang diekspor dengan data bertopeng (dengan asumsi diekspor oleh pengguna tanpa hak istimewa UNMASK ), dan database yang diimpor akan berisi data yang ditutupi secara statis.

Kueri untuk kolom bertopeng

sys.masked_columns Gunakan tampilan untuk mengkueri kolom tabel yang memiliki fungsi masking yang diterapkan padanya. Tampilan ini mewarisi dari sys.columns tampilan. Ini mengembalikan semua kolom dalam sys.columns tampilan, ditambah is_masked kolom dan masking_function , menunjukkan apakah kolom ditutupi, dan jika demikian, fungsi masking apa yang ditentukan. Tampilan ini hanya memperlihatkan kolom di mana ada fungsi masking yang diterapkan.

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;

Pembatasan dan batasan

Pengguna dengan CONTROL SERVER atau CONTROL di tingkat database dapat melihat data yang ditutupi dalam bentuk aslinya. Ini termasuk pengguna admin atau peran seperti sysadmin, serveradmin, db_owner dll.

Aturan masking tidak dapat ditentukan untuk jenis kolom berikut:

  • Kolom yang terenkripsi (Always Encrypted)

  • FILESTREAM

  • COLUMN_SET atau kolom jarang yang merupakan bagian kumpulan kolom.

  • Masker tidak dapat dikonfigurasi pada kolom komputasi, tetapi jika kolom komputasi bergantung pada kolom dengan MASK, maka kolom komputasi mengembalikan data yang ditutupi.

  • Kolom dengan data bermasker tidak dapat menjadi kunci untuk indeks FULLTEXT.

  • Kolom di dalam tabel eksternal PolyBase.

Untuk pengguna tanpa izin UNMASK, pernyataan READTEXT, UPDATETEXT, dan WRITETEXT yang tidak digunakan lagi tidak berfungsi dengan baik pada kolom yang dikonfigurasi untuk Masking Data Dinamis.

Menambahkan masker data dinamis diimplementasikan sebagai perubahan skema pada tabel yang mendasar, dan oleh karena itu tidak dapat dilakukan pada kolom dengan dependensi (misalnya, kolom yang direferensikan oleh kolom komputasi). Mencoba menambahkan masker data dinamis terhadap kolom dengan dependensi akan mengakibatkan kesalahan, ALTER TABLE ALTER COLUMN _columnname_ failed because one or more objects access this column. Untuk mengatasi pembatasan ini, Anda dapat terlebih dahulu menghapus dependensi, lalu menambahkan masker data dinamis lalu membuat ulang dependensi. Misalnya, jika dependensi disebabkan oleh indeks yang bergantung pada kolom tersebut, Anda dapat menghilangkan indeks, lalu menambahkan masker, lalu membuat ulang indeks dependen.

Setiap kali Anda memproyeksikan ekspresi yang mereferensikan kolom yang fungsi masking datanya ditentukan, ekspresi juga diselubungi. Terlepas dari fungsi (default, email, acak, string kustom) yang digunakan untuk menutupi kolom yang direferensikan, ekspresi yang dihasilkan akan selalu ditutupi dengan fungsi default.

Kueri lintas database yang mencakup dua database atau database Azure SQL yang berbeda yang dihosting di Instans SQL Server yang berbeda, dan melibatkan segala jenis perbandingan atau operasi gabungan pada kolom MASKED tidak memberikan hasil yang benar. Hasil yang dikembalikan dari server jarak jauh sudah dalam bentuk MASKED dan tidak cocok untuk perbandingan atau operasi gabungan apa pun secara lokal.

Catatan

Masking data dinamis tidak didukung saat tabel dasar yang mendasar direferensikan dalam tampilan terindeks.

Catatan Keamanan: Melewati masking menggunakan teknik inferensi atau brute-force

Masking data dinamis dirancang untuk menyederhanakan pengembangan aplikasi dengan membatasi paparan data dalam sekumpulan kueri yang telah ditentukan sebelumnya yang digunakan oleh aplikasi. Meskipun Masking Data Dinamis juga dapat berguna untuk mencegah paparan data sensitif yang tidak disengaja saat mengakses database produksi secara langsung, penting untuk dicatat bahwa pengguna yang tidak memiliki hak istimewa dengan izin kueri ad hoc dapat menerapkan teknik untuk mendapatkan akses ke data aktual. Jika ada kebutuhan untuk memberikan akses ad hoc tersebut, Audit harus digunakan untuk memantau semua aktivitas database dan mengurangi skenario ini.

Sebagai contoh, pertimbangkan prinsipal database yang memiliki hak istimewa yang memadai untuk menjalankan kueri ad hoc pada database, dan mencoba 'menebak' data yang mendasarinya dan pada akhirnya menyimpulkan nilai aktual. Asumsikan bahwa kita memiliki masker yang ditentukan pada [Employee].[Salary] kolom, dan pengguna ini terhubung langsung ke database dan mulai menebak nilai, akhirnya menyimpulkan [Salary] nilai dalam Employees tabel:

SELECT ID, Name, Salary FROM Employees
WHERE Salary > 99999 and Salary < 100001;
Id Nama Gaji
62543 Jane Doe 0
91245 John Smith 0

Ini menunjukkan bahwa masking data dinamis tidak boleh digunakan sendiri untuk sepenuhnya mengamankan data sensitif dari pengguna yang menjalankan kueri ad hoc pada database. Ini sesuai untuk mencegah paparan data sensitif yang tidak disengaja, tetapi tidak melindungi dari niat jahat untuk menyimpulkan data yang mendasar.

Penting untuk mengelola izin pada database dengan benar, dan untuk selalu mengikuti prinsip izin minimal yang diperlukan. Selain itu, ingatlah agar Audit diaktifkan untuk melacak semua aktivitas yang terjadi pada database.

Izin terperinci yang diperkenalkan di SQL Server 2022

Dimulai dengan SQL Server 2022 (16.x), Anda dapat mencegah akses tidak sah ke data sensitif dan mendapatkan kontrol dengan menutupinya ke pengguna yang tidak sah di berbagai tingkat database. Anda dapat memberikan atau mencabut izin UNMASK di tingkat database, tingkat skema, tingkat tabel, atau di tingkat kolom kepada pengguna, peran database, identitas Microsoft Entra, atau grup Microsoft Entra. Peningkatan ini memberikan cara yang lebih terperinci untuk mengontrol dan membatasi akses tidak sah ke data yang disimpan dalam database dan meningkatkan manajemen keamanan data.

Contoh

Membuat masker data dinamis

Contoh berikut membuat tabel dengan tiga jenis masker data dinamis yang berbeda. Contoh mengisi tabel, dan memilih untuk menampilkan hasilnya.

-- 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

Pengguna baru dibuat dan diberikan izin SELECT pada skema tempat tabel berada. Kueri dijalankan sebagai tampilan data bertopeng MaskingTestUser .

CREATE USER MaskingTestUser WITHOUT LOGIN;

GRANT SELECT ON SCHEMA::Data TO MaskingTestUser;
  
-- impersonate for testing:
EXECUTE AS USER = 'MaskingTestUser';

SELECT * FROM Data.Membership;

REVERT;

Hasilnya menunjukkan masker dengan mengubah data dari:

1 Roberto Tamburello 555.123.4567 RTamburello@contoso.com 10

Ke:

1 Rxxxxxo Tamburello xxxx RXXX@XXXX.com 91

di mana angka di DiscountCode acak untuk setiap hasil kueri.

Menambahkan atau mengedit masker pada kolom yang sudah ada

ALTER TABLE Gunakan pernyataan untuk menambahkan masker ke kolom yang sudah ada dalam tabel, atau untuk mengedit masker pada kolom tersebut.
Contoh berikut menambahkan fungsi masking ke LastName kolom:

ALTER TABLE Data.Membership
ALTER COLUMN LastName ADD MASKED WITH (FUNCTION = 'partial(2,"xxxx",0)');

Contoh berikut mengubah fungsi masking pada LastName kolom:

ALTER TABLE Data.Membership
ALTER COLUMN LastName VARCHAR(100) MASKED WITH (FUNCTION = 'default()');

Memberikan izin untuk melihat data yang tidak dikemas

Memberikan izin UNMASK memungkinkan MaskingTestUser untuk melihat data yang di-unmask.

GRANT UNMASK TO MaskingTestUser;

EXECUTE AS USER = 'MaskingTestUser';

SELECT * FROM Data.Membership;

REVERT;
  
-- Removing the UNMASK permission
REVOKE UNMASK TO MaskingTestUser;

Menghilangkan masker data dinamis

Pernyataan berikut menghilangkan masker pada kolom yang LastName dibuat dalam contoh sebelumnya:

ALTER TABLE Data.Membership
ALTER COLUMN LastName DROP MASKED;

Contoh izin terperinci

  1. Buat skema untuk berisi tabel pengguna:

    CREATE SCHEMA Data;
    GO
    
  2. Buat tabel dengan kolom bertopeng:

    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. Sisipkan data sampel:

    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. Buat skema untuk berisi tabel layanan:

    CREATE SCHEMA Service;
    GO
    
  5. Buat tabel layanan dengan kolom bertopeng:

    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. Sisipkan data sampel:

    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. Buat pengguna yang berbeda dalam 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. Berikan izin baca kepada pengguna dalam 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. Berikan izin UNMASK yang berbeda kepada pengguna:

    --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. Kueri data di bawah konteks pengguna ServiceAttendant:

    EXECUTE AS USER = 'ServiceAttendant';
    
    SELECT MemberID, FirstName, LastName, Phone, Email, BirthDay
    FROM Data.Membership;
    
    SELECT MemberID, Feedback, Rating
    FROM Service.Feedback;
    
    REVERT;
    
  11. Kueri data di bawah konteks pengguna ServiceLead:

    EXECUTE AS USER = 'ServiceLead';
    
    SELECT MemberID, FirstName, LastName, Phone, Email, BirthDay
    FROM Data.Membership;
    
    SELECT MemberID, Feedback, Rating
    FROM Service.Feedback;
    
    REVERT;
    
  12. Kueri data di bawah konteks pengguna ServiceManager:

    EXECUTE AS USER = 'ServiceManager';
    
    SELECT MemberID, FirstName, LastName, Phone, Email, BirthDay
    FROM Data.Membership;
    
    SELECT MemberID, Feedback, Rating
    FROM Service.Feedback;
    
    REVERT;
    
  13. Mengkueri data di bawah konteks pengguna ServiceHead

    EXECUTE AS USER = 'ServiceHead';
    
    SELECT MemberID, FirstName, LastName, Phone, Email, BirthDay
    FROM Data.Membership;
    
    SELECT MemberID, Feedback, Rating
    FROM Service.Feedback;
    
    REVERT;
    
  14. Untuk mencabut izin UNMASK, gunakan pernyataan T-SQL berikut:

    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;