在 Linux 上的 Db2 v11.5.7 中,我有一个简单的表:
create table admin.patient_data (
patientid int not null primary key,
patient_name varchar(10),
illness varchar(15),
doctor_name varchar(10)
);
insert into admin.patient_data values (1, 'Alice', 'illness A', 'DOCTOR1');
insert into admin.patient_data values (2, 'Bob', 'illness B', 'DOCTOR2');
select * from admin.patient_data;
结果:
PATIENTID PATIENT_NAME ILLNESS DOCTOR_NAME
----------- ------------ --------------- ----------
1 Alice illness A DOCTOR1
2 Bob illness B DOCTOR2
ILLNESS 列是敏感数据。我希望仅当列 DOCTOR_NAME 与 Db2 登录用户匹配时才显示此列。
create mask admin.patient_data on admin.patient_data
for column illness return
case when doctor_name = USER then illness else 'Masked data' end
enable;
alter table admin.patient_data activate column access control;
现在用户 DOCTOR1 连接到数据库并检查数据:
select * from admin.patient_data
它被退回:
PATIENTID PATIENT_NAME ILLNESS DOCTOR_NAME
----------- ------------ --------------- -----------
1 Alice illness A DOCTOR1
2 Bob Masked data DOCTOR2
在行 PATIENTID=2 列 ILLNESS 预计将被屏蔽。
但是医生受过教育,所以他/她知道所有的疾病,现在瞄准“疾病B”
db2 "select * from admin.patient_data where illness = 'illness B'"
它得到:
PATIENTID PATIENT_NAME ILLNESS DOCTOR_NAME
----------- ------------ --------------- -----------
2 Bob Masked data DOCTOR2
字段 ILLNESS 仍按预期标记,但现在因为有条件的 DOCTOR1 知道患者 Bob 患有“疾病 B”。
我希望最终用户可以按条件返回的值进行过滤。即:“疾病A”和“标记数据”。
有没有一些简单的解决方案来防止这种情况?我希望最后一个 select 语句不会返回任何记录。
这是按设计工作™:
如果要阻止对特定行的访问,则需要激活行访问控制并定义所需的行权限。
屏蔽是在流程的后期完成的,在将数据返回给最终用户之前,在执行 WHERE 条件之后。
如果要求是严格在数据库级别(而不是应用程序级别)进行屏蔽,就像所有医生都必须有权访问所有患者姓名一样,那么我看不到其他选择,然后重新设计 ER 模型。这种扼杀了应用于现有表格之上的主要“营销”思想掩蔽。
第一种选择是使用视图而不是数据屏蔽,应用程序访问视图而不是表。
第二种选择是将敏感数据和非敏感数据分隔在单独的表中。就像在“患者”表中具有“患者 ID”、“患者姓名”、“医生姓名”以及在具有“患者 ID”和“疾病”字段的单独表中单独的患者-疾病关系。或者在“患者”表中具有“患者 ID”、“患者姓名”、“医生姓名”和新字段“疾病 ID”,在新疾病表中具有疾病 ID 和疾病。然后在列掩码旁边还使用这两个单独的表中的行访问控制。