There are two areas that consistently trap newcomers to VPD. The problem occurs when an RLS policy function references an application context that is null. The reason the application context is null is because the namespace manager is trying to set the context on the table to which the RLS policy is being applied. This example begins by illustrating the working context. Recall the user’s department number is set by a logon trigger. The trigger calls the namespace manager, which sets the value by querying the LOOKUP_DEPT table: sec_mgr@KNOX10g> CONN scott/tiger Normally, the lookup table would not exist. It was created specifically to bypass this problem. Nevertheless, the mistake comes next when an RLS policy is added to the LOOKUP_DEPT table. To help with this example, an update policy will be added to the EMP table using the same policy function. Most often the context will be set from the same table the RLS policy will be enforced from which, as you will see, can’t be done: sec_mgr@KNOX10g> -- Add Dept level policy to lookup table. Querying from the lookup table shows the expected results. If you are the security administrator, you may feel nothing is wrong: sec_mgr@KNOX10g> -- rows are no longer visible Connecting as the SCOTT user, you can see the application context wasn’t set. The ramifications of this are that any RLS policies that are based on this context will not behave properly: sec_mgr@KNOX10g> CONN scott/tiger Recall the policy function being added restricts the user’s records to the department in which they work. The department number is stored in the context that is populated from the same table being restricted by the RLS policy. This recursive condition prevents the application context from being populated. The solution to this is to create a different object to be used for populating the application context. The object can be a table or a view. A view is the best because there is no data synchronization that needs to occur. If you create a view, the application context lookup should occur on the table, and the RLS policy should be applied to the view. If you did this the other way, it wouldn’t work because the RLS on the base table would still be in effect when the table was accessed by way of the view. Partitioned Fine-Grained Access ControlOracle introduced partitioned fine-grained access control in Oracle9i Database, which allows you to group together multiple policies and then enable and disable them easily. This is a useful concept when multiple policies exist on the same objects but have conflicting return values. Recall that Oracle logically ANDs all RLS policies. That is, if there are two policies, A and B, for the same object, then the resulting SQL will be the output of A and B. If policy A returns “deptno = 20” and policy B returns “deptno = 10”, then the resulting query will be “deptno = 20 and deptno = 10”. Because the deptno is either 10 or 20, this query results in zero rows. Partitioned fine-grained access control allows you to define which RLS policies you want to enable for the user session. This is done by setting the policy name into an application context. The database will then reference this policy name by looking at the value stored in the user’s application context and applying that RLS policy. Normally, I would include an example that illustrates some nuance of the technology. Fortunately, the Oracle Database Security Guide 10g has an excellent example of partitioned fine-grained access control. Including a different example here would be redundant. Column Sensitive VPDOracle Database 10g offers a new feature to VPD called Column Sensitive VPD. The objective of this feature is to invoke the security policy when a specific column is referenced. Let’s augment the security on the PEOPLE view to allow users to see only their own salaries. You do still want the user to see other columns of other user records. You can use the same PL/SQL function, USER_ONLY, for this new policy. The added parameter is SEC_RELEVANT_COLS. sec_mgr@KNOX10g> BEGIN Testing this code, you see a different result than you did with our view. When the SALARY column is queried, the VPD policy is invoked, and only one record is returned; when the SALARY column is not queried, then the policy isn’t invoked and all records are returned: sec_mgr@KNOX10g> CONN scott/tiger To make VPD behave like the column masking view example you saw in Chapter 10 you can use another new parameter to the ADD_POLICY procedure: SEC_RELEVANT_COLS_OPT. Oracle’s implementation is consistent with what was done in the view. That is, the values for the sensitive columns are null values. All the other columns and rows are returned: sec_mgr@KNOX10g> BEGIN The final query then results with null salary values for all but the invoking users: scott@KNOX10g> -- all_rows added as sec_relevant_cols_opt
The column sensitive option is ideal for privacy requirements. The column may be anything sensitive that you want to conceal—salary, a credit card number, patient diagnosis, financial status, and so on. This option allows you to store the sensitive information and the nonsensitive information together with the assurance that anytime someone requests the sensitive data, RLS will remove or mask the values.
blog comments powered by Disqus |
|
|
|
|
|
|
|