假设你有一个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策略中的恶意谓词函数是否会导致特权用户通过生成引用恶意函数的谓词来运行用户提供的代码,而这些代码在某种程度上是分开的.)
因此,在您的示例中,以下查询:
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
When a table alias is required (for example,parent object is a type
table) in the predicate,the name of the table or view itself must be
used as the name of the alias. The server constructs the transient
view as something like
select c1,c2,... from tab tab where <predicate>