MS SQL 資料遮罩

一直以來對資料庫的概念大多集中在儲存,撈資料,大量處理資料這一塊,對於權限控管這塊反倒是少著墨了,偶然從同事的口中得知資料遮罩這個有趣的東西可以對敏感性資料做處理,不但處理效果相當好,而且也相當的好上手啊

當組織規模達到一定程度時,其他部門也許也會需要你提供資料給他們

通常會有兩種方式,第一種就是我們提供 API 給對方,第二種就是提供 sql 帳號讓他們自行選擇資料

但資料面通常也會包含了敏感資料,比方姓名,電話,信用卡資料,薪資等等的

在此先不討論這兩種作法的好壞

直接跳到懶人式作法,也就是第二種作法

假設我們有一個 table 名為 user,而裡面的資料是這樣子的

而我們需要開啟一組帳號給內部使用者做資料分析,但我們又不希望敏感性的資料外洩

這時候資料遮罩就完全派上用場了

我們想把user name 變成只有抓取前、後一個字元

password 顯示出看不出原本的密碼即可 (雖說應該用 MD5 encode存進來,但這邊只為了展示使用 raw data)

Birthday 則是顯示 1900-01-01

Phone 顯示前兩碼,後面以遮罩顯示

Age 則隨機顯示20-50歲的使用者

這麼一來,我們就可以練習到大部份的函式了

ALTER TABLE [user] ALTER COLUMN username ADD MASKED WITH(FUNCTION='partial(1, "xxx", 1)') 
ALTER TABLE [user] ALTER COLUMN password ADD MASKED WITH(FUNCTION='default()') 
ALTER TABLE [user] ALTER COLUMN email ADD MASKED WITH(FUNCTION='email()') 
ALTER TABLE [user] ALTER COLUMN birthday ADD MASKED WITH(FUNCTION='default()') 
ALTER TABLE [user] ALTER COLUMN phone ADD MASKED WITH(FUNCTION='partial(2, "********", 0)') 
ALTER TABLE [user] ALTER COLUMN age ADD MASKED WITH(FUNCTION='random(20, 50)') 

接著我們產生一個使用者 u,但他並沒有login 的權限,所以也不需要建立密碼給他

接著讓他有對 user select的權限

CREATE USER u WITHOUT LOGIN
GRANT SELECT ON [user] TO u

EXEC AS USER = 'u'
SELECT * FROM [user] 
REVERT

是不是結果讓人相當滿意呢?

如果今天你想要讓使用者 u 看到 raw data,只要解除 u 的遮罩就好了,其他使用者還是繼續做鬼遮眼的動作

GRANT UNMASK TO u

是不是太容易了啊

反悔了,u 繼續鬼遮眼

REVOKE UNMASK TO u

 

當你發現 姓名資料實在是不太重要,想要移除對所有可以select 到這張table的遮罩時

你可以使用下面的語法,這麼一來任何 login, 權限, 程式碼都不需要動, 可說是相當相當的便利啊

ALTER TABLE [user] ALTER COLUMN username DROP MASKED

其他討論

資料遮罩其實猜的到,底層的實作是在 select 資料的時候才做的

在 where, inner join 的時候是不可能做遮罩的

所以下面的 sql 是完全可以正常運作的

EXEC AS USER = 'u'
SELECT u.* FROM [user] u
inner join [user] uu on u.Password = uu.Password
where u.Password like '12%'
REVERT

聰明如你應該也想的到,如果今天這個欄位是 salary的話

如果是有心人的話,還是可以用二分搜尋法慢慢找出大概的資料

所以MSDN上有這麼一句話 「它適合防止機密資料不慎洩露,但無法防止惡意推斷基礎資料」

 

參考資料

https://dotblogs.com.tw/stanley14/2016/03/19/090752

https://docs.microsoft.com/zh-tw/sql/relational-databases/security/dynamic-data-masking?view=sql-server-2017