動態資料遮罩 (DDM)
動態資料遮罩 (DDM) 會隱藏敏感資訊,同時仍允許存取已遮罩的欄位。DDM 不會變更儲存的資料。相反地,它只會在 SELECT
查詢期間以其模糊的形式呈現資料。這旨在提供一定程度的保護,以防止意外資料外洩。但是,任何有權直接存取 SSTable 檔案的人員都將能夠讀取清除的資料。
遮罩函數
DDM 基於一組 CQL 原生函數,這些函數會隱藏敏感資訊。可用的函數為
函數 | 說明 |
---|---|
|
將第一個參數替換為 範例
|
|
用相同類型的任意固定預設值替換其參數。對於文字值,這將是 可變長度多值類型(例如清單、集合和映射)會被遮罩為空集合。 固定長度多值類型(例如元組、使用者定義類型 (UDT) 和向量)會被遮罩,方法是將其每個值替換為該值類型的預設遮罩值。 範例
|
|
取代第二個引數中的第一個引數為替換值。替換值需要與被取代的值為相同類型。 範例
|
|
傳回第一個 範例
|
|
傳回第一個 範例
|
|
傳回包含第一個引數雜湊的 範例
|
這些函數可以用於SELECT
查詢,以取得資料的模糊檢視。例如
CREATE TABLE patients (
id timeuuid PRIMARY KEY,
name text,
birth date
);
INSERT INTO patients(id, name, birth) VALUES (now(), 'alice', '1982-01-02');
INSERT INTO patients(id, name, birth) VALUES (now(), 'bob', '1982-01-02');
SELECT mask_inner(name, 1, null), mask_default(birth) FROM patients;
// system.mask_inner(name, 1, NULL) | system.mask_default(birth)
// -----------------------------------+----------------------------
// b** | 1970-01-01
// a**** | 1970-01-01
將遮罩函數附加到表格欄位
遮罩函數可以永久附加到表格的任何欄位。如果定義了遮罩欄位,SELECT
查詢將永遠以遮罩形式傳回欄位值。遮罩對執行SELECT
查詢的使用者來說是透明的。知道欄位已被遮罩的唯一方法是參閱表格定義。
這是一個預設停用的選擇性功能。若要使用此功能,請在cassandra.yaml
中啟用dynamic_data_masking_enabled
屬性。
表格欄位的遮罩可以在CREATE TABLE
中定義,以建立表格架構。這個範例使用具有兩個引數的mask_inner
函數
CREATE TABLE patients (
id timeuuid PRIMARY KEY,
name text MASKED WITH mask_inner(1, null),
birth date MASKED WITH mask_default()
);
在這個資料上使用 SELECT
查詢時,mask_inner
函數需要三個參數,但當將函數附加到表格架構時,第一個參數總是會被省略。第一個參數的值總是會被解釋為遮罩欄位的數值,在本例中為 text
欄位。
基於相同原因,在建立表格架構時,使用遮罩函數 mask_default
沒有任何參數,但在 SELECT
查詢中使用時需要一個參數。
資料可以正常插入遮罩表格中,而不會被變更。例如
INSERT INTO patients(id, name, birth) VALUES (now(), 'alice', '1984-01-02');
INSERT INTO patients(id, name, birth) VALUES (now(), 'bob', '1982-02-03');
SELECT
查詢將會傳回遮罩資料。遮罩函數將會自動套用至欄位值。
SELECT name, birth FROM patients;
// name | birth
// -------+------------
// a**** | 1970-01-01
// b** | 1970-01-01
ALTER TABLE
查詢可用於變更表格欄位上的遮罩函數。
ALTER TABLE patients ALTER name
MASKED WITH mask_default();
類似地,遮罩函數可以使用 ALTER TABLE
查詢從欄位中分離。
ALTER TABLE patients ALTER name
DROP MASKED;
權限
一般使用者在建立時沒有 UNMASK
權限,並且會看到遮罩值。授予使用者 UNMASK
權限,讓他們可以擷取遮罩欄位的未遮罩值。超級使用者會在建立時自動取得 UNMASK
權限,並且會在 SELECT
查詢結果中看到未遮罩值。
例如,假設我們有一個包含遮罩欄位的表格
CREATE TABLE patients (
id timeuuid PRIMARY KEY,
name text MASKED WITH mask_inner(1, null),
birth date MASKED WITH mask_default()
);
然後我們在表格中插入一些資料
INSERT INTO patients(id, name, birth) VALUES (now(), 'alice', '1984-01-02');
INSERT INTO patients(id, name, birth) VALUES (now(), 'bob', '1982-02-03');
LOGIN unprivileged
SELECT name, birth FROM patients;
// name | birth
// -------+------------
// a**** | 1970-01-01
// b** | 1970-01-01
接著我們為表格建立兩個具有 SELECT
權限的使用者,但我們只授予其中一個使用者 UNMASK
權限
CREATE USER privileged WITH PASSWORD 'xyz';
GRANT SELECT ON TABLE patients TO privileged;
GRANT UNMASK ON TABLE patients TO privileged;
CREATE USER unprivileged WITH PASSWORD 'xyz';
GRANT SELECT ON TABLE patients TO unprivileged;
具有 UNMASK
權限的使用者可以看到明確的未遮罩資料
LOGIN privileged
SELECT name, birth FROM patients;
// name | birth
// -------+------------
// alice | 1984-01-02
// bob | 1982-02-03
沒有 UNMASK
權限的使用者只能看到遮罩資料
LOGIN unprivileged
SELECT name, birth FROM patients;
// name | birth
// -------+------------
// a**** | 1970-01-01
// b** | 1970-01-01
UNMASK
權限就像任何其他權限一樣,可以隨時撤銷
REVOKE UNMASK ON TABLE patients
FROM privileged;
請注意,當驗證已停用時,匿名預設使用者具有所有權限,包括 UNMASK
權限,並且可以看到未遮罩資料。換句話說,只有在啟用驗證時,將資料遮罩函數附加到欄位才有意義。
只有具有 UNMASK
權限的使用者才能在 SELECT
查詢的 WHERE
子句中使用遮罩欄位。沒有 UNMASK
權限的使用者無法使用此功能。此功能可防止惡意使用者透過執行窮舉式暴力破解查詢來查看明確資料。沒有 UNMASK
權限的使用者將會看到以下內容
CREATE USER untrusted_user WITH PASSWORD 'xyz';
GRANT SELECT ON TABLE patients TO untrusted_user;
LOGIN untrusted_user
SELECT name, birth FROM patients WHERE name = 'Alice' ALLOW FILTERING;
// Unauthorized: Error from server: code=2100 [Unauthorized] message="User untrusted_user has no UNMASK nor SELECT_UNMASK permission on table k.patients"
在某些使用案例中,受信任的資料庫使用者需要產生未受信任的外部使用者將會查詢的遮罩資料。例如,受信任的應用程式可以連線到資料庫,並透過查詢擷取將顯示給其最終使用者的遮罩資料。在這種情況下,可以授予受信任的使用者 (應用程式) SELECT_MASKED
權限。此權限讓使用者可以在 SELECT
查詢的 WHERE
子句中查詢遮罩欄位,同時仍然只在查詢結果中看到遮罩資料
CREATE USER trusted_user WITH PASSWORD 'xyz';
GRANT SELECT, SELECT_MASKED ON TABLE patients TO trusted_user;
LOGIN trusted_user
SELECT name, birth FROM patients WHERE name = 'Alice' ALLOW FILTERING;
// name | birth
// -------+------------
// a**** | 1970-01-01
自訂函式
使用者定義函式 (UDF) 可以附加到資料表欄位。用於遮罩的 UDF 應屬於與遮罩資料表相同的鍵空間。要遮罩的欄位值將傳遞為附加 UDF 的第一個引數。因此,附加到欄位的 UDF 應至少有一個引數,而且該引數應與遮罩欄位具有相同的類型。此外,附加的 UDF 應傳回與遮罩欄位相同的類型值
CREATE FUNCTION redact(input text)
CALLED ON NULL INPUT
RETURNS text
LANGUAGE java
AS 'return "redacted";';
CREATE TABLE patients (
id timeuuid PRIMARY KEY,
name text MASKED WITH redact(),
birth date
);
這會在資料表架構和函式之間建立相依性。在這個相依性存在時,任何嘗試刪除函式的動作都將遭到拒絕。因此,您必須先刪除資料表中的遮罩欄位,才能刪除函式
ALTER TABLE patients ALTER name
DROP MASKED;
刪除欄位、包含欄位的資料表或包含資料表的鍵空間也會移除相依性。
聚合函式 無法用作遮罩函式。