SQL Server 2016 – Dynamic Data Masking

Kontynuujemy naszą serię na temat nowości w najnowszej wersji SQL Server 2016. Bohaterem dzisiejszego artykułu jest technologia Dynamic Data Masking pozwalająca na ukrywanie wrażliwych danych przed niepowołanymi osobami. technologia ta już od jakiegoś czasu jest ogólnie dostępna w ramach chmurowej bazy SQL Azure, a już od pierwszego czerwca mogą się nią cieszyć użytkownicy najnowszego SQL Server. W ramach niniejszego artykułu postaram się przedstawić schemat działania niniejszej technologii, określić możliwe scenariusze użycia oraz praktycznie pokazać jak tę technologię zaimplementować – zaczynajmy!

DynamicDataMasking_schema
Większość z nas pracuje z różnego rodzaju bazami danych. Bazy te przechowują najróżniejsze dane od danych produkcyjnych, przez dane handlowe, aż po dane finansowe. Wspólnym mianownikiem łączącym każdą bazę danych jest fakt, iż znajdują się w niej dane o szczególnej wrażliwości, które same w sobie powinny być zabezpieczone przed dostępem osób trzecich. Istnieje bardzo dużo sposobów na radzenie sobie z tego typu sytuacjami – można zaimplementować algorytmy szyfrujące bądź też po prostu przerzucić sposób wyświetlania danych na aplikację. Alternatywę dla tego typu rozwiązań możemy znaleźć w najnowszej implementacji SQL Server czyli wspomniane Dynamic Data Masking. Technologia ta pozwala na całkowite lub częściowe ukrycie danych według określonych zasad w ramach konkretnej kolumny w tabeli przy niemal całkowitej transparentności dla istniejących aplikacji. Jak to zrobić? Sprawdźmy to na konkretnym przykładzie.

Na samym początku tradycyjnie stworzymy sobie testową bazę danych na potrzeby naszej demonstracji.

Następnie stworzymy sobie testowego użytkownika, którego będziemy używać w celu zilustrowania różnego poziomu dostępu do naszych danych. Użytkownik ten będzie miał możliwość odczytywania danych w ramach naszej testowej bazy danych.

W kolejnym kroku stworzymy sobie testową tabelę w ramach nowopowstałej bazy danych i wstawimy do niej pojedynczy wiersz zawierający teoretycznie wrażliwe dane:

W tym miejscu przechodzimy do meritum niniejszego artykułu i włączymy mechanizm Dynamic Data Masking dla kolumny AccountNumber.

Jak można zauważyć powyżej do włączenia Dynamic Data Masking należy użyć komendy ALTER TABLE.. ALTER COLUMN. Następnie należy wskazać, iż chcemy włączyć maskę danych (ADD MASKED WITH) oraz wskazać funkcję, której chcemy użyć do zamaskowania naszych danych. W powyższym przykładzie użyliśmy funkcji o nazwie default(), która zamaskuje nasze dane w zależności od typu danych jaki ma dana kolumna.

Aby przetestować działanie Dynamic Data Masking stwórzmy procedurę, która będzie uruchamiana jako wcześniej utworzony użytkownik  TestUser.

Następnie wykonajmy powyższą procedurę i sprawdźmy co otrzymamy w rezultacie.

DynamicDataMasking

Jak można zauważyć dane zostały zamaskowane znakami “x” tak więc testUser może odpytać dane ale nie jest w stanie odczytać ich konkretnej wartości. Co natomiast jeżeli uruchomimy zapytanie naszym bieżącym użytkownikiem będącym sysadminem na serwerze? Sprawdźmy to!

dynamicDataMasking2

Jak widać sysadmin sam w sobie posiada uprawnienia do odczytania niezamaskowanych danych. Spróbujmy taki przywilej nadać naszemu testowemu użytkownikowi. Wraz z technologią Dynamic Data Masking dostaliśmy uprawnienie UNMASK, które możemy nadać poszczególnym użytkownikom – zróbmy to i wywołajmy procedurę w celu weryfikacji.

dynamicDataMasking2

Jak widać uprawnienie zostało nadane poprawnie i testUser może bez problemu odczytywać dane. Ale czy wyświetlanie “x” to jedyna możliwość opisywanego mechanizmu? Oczywiście nie – mamy do dyspozycji , kilka funkcji maskujących, które przedstawię poniżej – zanim to zrobię musimy odebrać uprawnienia, które dopiero co nadaliśmy.

Kolejną funkcją, którą się zajmiemy jest email(), która przeznaczona jest do szyfrowania adresów poczty elektronicznej.

dynamicDataMasking3

Jak widać, funkcja email() ukryła nazwę adresu email zostawiając widoczne jedynie pierwszą literę i znak @. Spośród dostępnych funckji mamy również partial() umożliwiającą uzyskanie niestandardowego maskowania. Poniższy przykład zwróci dla pola Phone jedynie pierwsze 3 cyfry  następnie znak “X” i ostatnią cyfrę danego numeru telefonu.

dynamicDataMasking4

Ostatnią wbudowaną funkcją Dynamic Data Masking jest funkcja o znajomo brzmiącej nazwie random(), która maskuje dane pole poprzez podstawienie losowego numeru z podanego przez nas zakresu. Poniżej funkcja wybrała liczbę 44518 z zakresu od 10000 do 100000 i podstawiła ją jako maskę dla pola SecurityNumber.

dynamicDataMasking5

To by było na tyle jeśli chodzi o przygotowane przez Microsoft funkcje związane z Dynamic Data Masking. Myślę, że w większości przypadków podane cztery funkcje w zupełności wystarczą i spełnią określone wymagania biznesowe. Usuwanie maski z kolumny odbywa się również w mało skomplikowany sposób – wystarczy wykonać odpowiednie zapytanie typu DDL tak jak zostało to przedstawione poniżej:

Otwarta pozostaje kwestia monitorowania, które kolumny mają zawartą w sobię maskę, a które nie – gdyż nie jesteśmy w stanie wizualnie ocenić czy maska została zastosowana czy też nie. Oczywiście istniejące widoki systemowe zostały zaktualizowane tak aby takiej informacji nam dostarczać. Poniższe zapytanie zwróci nam nazwę kolumny w ramach konkretnej tabeli, która została zamaskowana oraz dodatkowo nazwę funkcji użytej do jej zamaskowania.

dynamicDataMasking7

Dzięki temu możemy monitorować, gdzie i na jakich zasadach założono funkcję maskującą. Wielu z wam może przyjść do głowy pytanie – czy nie ma możliwości obejścia tego mechanizmu np. poprzez wstawienie danych do tabeli tymczasowej? Myślę, że najlepszą odpowiedzią na to pytanie będzie sprawdzenie tego faktu. Stwórzmy sobie kolejną funkcję, która pobierze dane z tabeli jako testUser nie mający prawa do odczytu niezamaskowanych danych i wstawi do globalnej tabeli tymczasowej:

Następnie po prostu odpytajmy tą globalną tabelę zwykłym zapytaniem adhoc jako nasz bieżący użytkownik (sysadmin) mający prawa do odczytu niezamaskowanych danych:

dynamicDataMasking5

Jak widać dane w tabeli tymczasowej pozostały zamaskowane – dzięki temu dane pozostają bezpieczne nawet po ich przeniesieniu do innych struktur. Jednakże nie należy zawierzać bezpieczeństwa danych temu mechanizmowi ponieważ odpowiednio napisane zapytanie SELECT może odnaleźć nasze dane nawet jeśli są one zamaskowane. Oczywiście mechanizm Dynamic Data Masking nie jest pozbawiony ograniczeń np. mechanizmu nie można użyć gdy używamy technologii FILESTREAM lub też Always Encrypted, mimo to technologia ta rozszerza nasz wachlarz możliwości co zawsze powinniśmy przyjąć z otwartymi ramionami.

Adrian Chodkowski
Follow me

Adrian Chodkowski

SQL geek, Data enthusiast, Consultant & Developer
Adrian Chodkowski
Follow me

Leave a Comment

Your email address will not be published. Required fields are marked *