我一直在阅读Oracle VPD(虚拟专用数据库,a.k.a。细粒度安全性,基于标签的安全性的基础)的文档,而且我正在抓紧困难。 VPD如何防止用户使用WHERE
子句中的恶意函数泄露信息?
假设您有一个VPD策略,可生成类似cust_no = SYS_CONTEXT('order_entry', 'cust_num');
的静态谓词(如the Oracle VPD tutorial中所示)。
这导致查询被重写,所以:
SELECT * FROM orders;
变为:
SELECT * FROM orders
WHERE cust_no = SYS_CONTEXT('order_entry', 'cust_num');
到目前为止很好。但是如果用户写道:
SELECT * FROM orders WHERE my_malicious_function(secret_column);
?其中my_malicious_function
将其看到的每个值插入恶意用户控件所拥有的另一个表中,这样他们就可以通过选择该表来查看秘密数据。
VPD重写者将根据文档制作类似的内容:
SELECT * FROM orders
WHERE cust_no = SYS_CONTEXT('order_entry', 'cust_num')
AND my_malicious_function(secret_column);
但Oracle可以自由地重新订购WHERE
中的子条款。是什么阻止它首先运行my_malicious_function
,如果它认为那将是更便宜或更具选择性的谓词? (当安全条件是SYS_CONTEXT
查找时,不太可能,但如果条件是针对另一个表的子查询,或者是自己的UDF,则很可能。)
我已阅读文档,但我没有看到它在执行VPD谓词与用户提供的谓词时指定任何排序保证。是否有这样的保证或任何其他机制来防范恶意谓词函数?
(我也很好奇VPD策略中的恶意谓词功能是否会导致特权用户通过生成引用恶意功能的谓词来运行用户提供的代码,而这些代码在某种程度上是分开的。 )
答案 0 :(得分:3)
“恶意功能”在应用VPD策略后运行,因此无法看到隐藏数据。
因此,在您的示例中,以下查询:
SELECT * FROM orders WHERE my_malicious_function(secret_column);
重写为:
SELECT * FROM (
SELECT * FROM orders orders
WHERE cust_no = SYS_CONTEXT('order_entry', 'cust_num')
)
WHERE my_malicious_function(secret_column);
因此,该函数仅对满足VPD谓词的行执行。
参考:http://docs.oracle.com/cd/E11882_01/appdev.112/e40758/d_rls.htm#i1005326
当需要表别名时(例如,父对象是一种类型 table)在谓词中,表或视图本身的名称必须是 用作别名的名称。服务器构造瞬态 查看类似
的内容
select c1, c2, ... from tab tab where <predicate>