Exforsys

Home arrow Technical Training arrow Oracle 11g Tutorial

Oracle VPD implementation

Author:      Published on: 24th Oct 2011

1. What is Oracle Virtual Private Database(VPD)

Oracle has provided several solutions to ensure and secure the database. An efficient security policy not only prevents the database against the database corruption or hacking threats but also minimizes the risk of unprivileged user access. Several data security surveys have concluded that unauthorized data access to unprivileged users is a frequent severe threat to the data. Simple password settings, DBA roles and grants or user accounts are just not enough to monitor the data security of an organization.

Ads

The tutorial discusses one of the security methods which allow a user to see only the privileged data i.e. an explicit policy will restrict the user data access. The security feature is known as Virtual Private Database.

2. Virtual Private Database: The Need

Quite often, we encounter a traditional database design which follows the protocol of single Master server with multiple user accounts to access it.

For instance, a table designed to hold the data for different sub-entities, each one of them differentiated by a key column. An employee table can hold the employees data flowing from all locations. Table structure and sample data can be as below.

Now, a user from Australia (AUS) must have the privilege to view or modify employee details working in AUS only. Several options tend to achieve this problem

  • Local servers must maintain only local data
  • For Single master servers, one table per location must exist. Alternatively, separate views for each location can also be created.
  • For single Master servers, each query must be filtered (WHERE clause) based on ‘Location’.

The third option seems most straightforward, basic oriented and self explanatory, but still runs the risk of data authorization. But it comes out with certain potential problems like code development, maintenance overhead, and most importantly The Protocol follow up; no surety of how soon the protocol would vanish in large applications.

Therefore, Oracle extended the same concept to create Virtual Private Database for each location, where a local user would be able to view the data from its respective VPD only.

From the above table, three abstract VPDs can be easily extracted. First VPD would hold employee data from GER, second one from AUS and third one from RUS.

3. Virtual Private Database: The understanding and implementation

VPD works with the help of security policies and context to ensure the fine grained control on database objects. Virtual Private database policy dynamically appends the WHERE clause in SELECT queries and DML operations on the target table or view or synonyms.

It enables the creation and setting of security policies, which ensure authorized data access at row and column level. Note that VPD actions and objectives are limited up to data access operations (query and DMLs) only and does not supports data definitions (DDL).

How it works?

Whenever a user tries to access a table, the VPD policy on the table is activated. The figure below shows the process of VPD policy evaluation and query execution.

So, if a user from AUS queries the EMPLOYEES table as

SELECT * FROM EMPLOYEES

The VPD policy function appends the LOCATION filter and the server rewrites the above query as

SELECT * FROM EMPLOYEES WHERE LOCATION=’AUS’

Since the VPD policy execution is dynamic, users cannot view the data from other locations.

 4. VPD implementation 

Implementation of VPD in database involves the below steps, which we shall discuss in detail thereafter.

  1. Create a Policy Function
  2. Attach the Policy function to the Table

4.1. Creating a Policy function

A Policy is a condition to filter the target data, which appears as virtual database for the authorized user. During its evaluation, the server executes and prepares the predicate i.e. the WHERE clause. It might be a performance hit since an extra amount of time is involved in the query execution. This cause branches a Policy into two categories, Static Policy and Dynamic Policy.

Static policies are the one which are evaluated only once for each query. In the first execution, the policy result is cached in SGA. Thus, for the subsequent executions of the same query, the cached policy function result is used.

Dynamic Policies are evaluated each time it is invoked.

4.2. Usage Notes

The Policy function must be created with definer’s rights, not with the Invoker’s rights.

  • Policy functions can either hardcode the predicate condition (static) or use context attributes to define a predicate (dynamic).
  • Multiple policies can be imposed on a table

4.3. Creating a Policy

Once the policy function is associated with a database object (Table, views or synonyms), the security policy creation process is completed. A policy handling is done using DBMS_RLS package subprograms. The package serves to achieve all the objectives in regards to row and column level security in database tables, view or synonyms. The DBA must grant EXECUTE privilege on the DBMS_RLS package to the user, which intends to implement VPD.

  • DBMS_RLS.ADD_POLICY - Adds a policy to a table, view, or synonym
  • DBMS_RLS.ENABLE_POLICY - Enables (or disables) a policy you previously added to a table, view, or synonym
  • DBMS_RLS.REFRESH_POLICY - Invalidates cursors associated with non static policies
  • DBMS_RLS.DROP_POLICY - To drop a policy from a table, view, or synonym

4.4. Illustration

4.4.1. In the master server (which can be accessed globally), EMPLOYEES table contains employee details (NAME, JOB and LOCATION) from various locations. A user from each location is able to see the details of the EMPLOYEES table.

Sample Code
  1. SQL> SELECT * FROM EMPLOYEES;
  2.  
  3. EMPNAME    EMPJOB     LOCAT
  4. ---------- ---------- -----
  5. John       DEV        GER
  6. Kate       ADM        GER
  7. Miller     HR         AUS
  8. Andy       DEV        AUS
  9. Mac        DEV        AUS
  10. Dan        ADM        RUS
  11. Philip     HR         RUS
  12.  
  13. 7 rows selected.
Copyright exforsys.com


The SCOTT user creates a policy function, which returns a condition to filter the LOCATION by AUS.

Sample Code
  1. CREATE OR REPLACE FUNCTION F_LOC_POLICY (p_schema VARCHAR2, p_obj VARCHAR2)
  2. RETURN VARCHAR2
  3. IS
  4. BEGIN
  5.   RETURN 'LOCATION=''AUS''';
  6. END;
  7. /
  8.  
  9. FUNCTION created.
Copyright exforsys.com


The above policy function can be used to create a Policy EMPLOCATION using DBMS_RLS package. Note the SQL statement type parameter to specify the VPD protected statements.

Sample Code
  1. BEGIN
  2. DBMS_RLS.add_policy
  3. (object_schema => ‘SCOTT’,
  4. object_name => ‘EMPLOYEES’,
  5. policy_name => ‘EMPLOCATION’,
  6. function_schema => ‘SCOTT’,
  7. policy_function => ‘F_LOC_POLICY’,
  8. statement_types =>SELECT, UPDATE, INSERT,
  9. update_check => TRUE );
  10. END;
  11. /
Copyright exforsys.com


Query the EMPLOYEES table to get the employee which belong to AUS only

Sample Code
  1. SQL> SELECT * FROM EMPLOYEES;
  2.  
  3. EMPNAME    EMPJOB     LOCAT
  4. ---------- ---------- -----
  5. Miller     HR         AUS
  6. Andy       DEV        AUS
  7. Mac        DEV        AUS
Copyright exforsys.com


5. Policy Function using Context attributes

The above Policy function uses hardcoded information to prepare the predicate. In large and extending application, it might violate the application standards. Since the predicate information is set for the user, it can make use of the persistent session variables. Let us catch up the Policy function using Contexts.

5.1. Context

Oracle defines certain attributes in key-value format under a label, which reveal relevant information about the user in a session. The label is known as ‘Namespace’, while key-value pair is a ‘Name-Value’ set. They are stored in a secure data cache of UGA (user Global Area) for session persistence and faster access in applications. A context can be created, modified and deleted.

Since the Policy predicate is a deemed feature of the user in a session, it can be realized as a context attribute.

5.1.1. Creation of a Context

The Context creation requires a trusted package, which has to be created by the user.

Sample Code
  1. CONN SCOTT/TIGER
  2. Connected.
  3.  
  4. SQL> CREATE OR REPLACE PACKAGE PKG_CONTEXT IS
  5.   2  PROCEDURE P_SET_CONT (P_VAL VARCHAR2);
  6.   3  END;
  7.   4  /
  8.  
  9. PACKAGE created.
Copyright exforsys.com


The package takes a value as input and assigns it to LOCATION attribute under LOC_CONTEXT namespace. The context shall be created using this namespace only.

Sample Code
  1. SQL>  CREATE OR REPLACE PACKAGE BODY PKG_CONTEXT IS
  2.   2    PROCEDURE P_SET_CONT (P_VAL VARCHAR2)
  3.   3    IS
  4.   4    BEGIN
  5.   5       DBMS_SESSION.set_context(namespace => 'LOC_CONTEXT',
  6.                                    attribute => 'LOCATION' ,
  7.                                    VALUE => P_VAL);
  8.   6    END;
  9.   7   END;
  10.   8  /
  11.  
  12. PACKAGE BODY created.
Copyright exforsys.com


A DBA can create the context with the user’s trusted package

Sample Code
  1. SQLPLUS / AS SYSDBA
  2. Connected.
  3.  
  4. SQL> CREATE CONTEXT LOC_CONTEXT USING SCOTT.PKG_CONTEXT;
  5.  
  6. Context created.
Copyright exforsys.com


5.1.2. Verify the Context Setting

Sample Code
  1. CONN SCOTT/TIGER
  2. Connected
Copyright exforsys.com


Explicitly set the context by executing the Package PKG_CONTEXT

Sample Code
  1. SQL> EXEC PKG_CONTEXT.P_SET_CONT;
  2.  
  3. PL/SQL PROCEDURE successfully completed.
Copyright exforsys.com


Query the LOCATION attribute of namespace LOC_CONTEXT using SYS_CONTEXT function.

Sample Code
  1. SQL>  SELECT SYS_CONTEXT('LOC_CONTEXT','LOCATION') FROM DUAL;
  2.  
  3. SYS_CONTEXT('LOC_CONTEXT','LOCATION')
  4. -----------------------------------------
  5. AUS
Copyright exforsys.com


5.1.3. Re define the Policy Function

The policy function has to be modified to remove hardcoded predicate clause and include Context.

Sample Code
  1. CREATE OR REPLACE FUNCTION F_LOC_POLICY (p_schema VARCHAR2, p_obj VARCHAR2)
  2. RETURN VARCHAR2
  3. IS
  4. BEGIN
  5.   RETURN 'LOCATION='||'sys_context(''LOC_CONTEXT'',''LOCATION'')';
  6. END;
  7.  
  8. FUNCTION created.
Copyright exforsys.com


5.1.4. Re associate the policy with the EMPLOYEES table

Sample Code
  1. BEGIN
  2. DBMS_RLS.add_policy
  3. (object_schema => ‘SCOTT’,
  4. object_name => ‘EMPLOYEES’,
  5. policy_name => ‘EMPLOCATION’,
  6. function_schema => ‘SCOTT’,
  7. policy_function => ‘F_LOC_POLICY’,
  8. statement_types =>SELECT, UPDATE, INSERT,
  9. update_check => TRUE );
  10. END;
Copyright exforsys.com


5.1.5. Verify the VPD policy by querying the table

Sample Code
  1. SQL> SELECT * FROM EMPLOYEES;
  2.  
  3. EMPNAME    EMPJOB     LOCAT
  4. ---------- ---------- -----
  5. Miller     HR         AUS
  6. Andy       DEV        AUS
  7. Mac        DEV        AUS
Copyright exforsys.com


5.1.6. Create a LOGON trigger to automate the Context setting process for a user

To avoid explicit context setting, usually, DBAs set the context as soon as a user logs in to the database. This can be done by creating a LOGON trigger and invoking the context setting program.

Sample Code
  1. SQLPLUS / AS SYSDBA
  2. Connected.
  3.  
  4. CREATE OR REPLACE TRIGGER ON_LOGON
  5. AFTER LOGON
  6. ON DATABASE
  7. BEGIN
  8. IF USER='SCOTT' THEN
  9.  SCOTT.PKG_CONTEXT.P_SET_CONT('AUS');
  10. END IF;
  11. END;
  12. /
  13.  
  14. TRIGGER created.
Copyright exforsys.com


5.1.7. Verify the working of the LOGON trigger

Disconnect and re-log into the database to observe the VPD effect

Sample Code
  1. CONN SCOTT/TIGER
  2. Connected.
  3.  
  4. SQL> SELECT * FROM employees;
  5.  
  6. EMPNAME              EMPJOB               LOCAT
  7. -------------------- -------------------- -----
  8. Miller               HR                   AUS
  9. Andy                 DEV                  AUS
  10. Mac                  DEV                  AUS
Copyright exforsys.com


5.1.8. Modify the LOGON trigger definition to alter the context

For verification, I shall just change the context setting call during the LOGON trigger

Sample Code
  1. SQLPLUS / AS SYSDBA
  2. Connected.
  3.  
  4. CREATE OR REPLACE TRIGGER ON_LOGON
  5. AFTER LOGON
  6. ON DATABASE
  7. BEGIN
  8. IF USER='SCOTT' THEN
  9.  SCOTT.PKG_CONTEXT.P_SET_CONT(‘GER’);
  10. END IF;
  11. END;
  12.  
  13. TRIGGER created.
Copyright exforsys.com


Sample Code
  1. SQL> SELECT * FROM employees;
  2.  
  3. EMPNAME              EMPJOB               LOCAT
  4. -------------------- -------------------- -----
  5. John                 DEV                  GER
  6. Kate                 ADM                  GER
Copyright exforsys.com


6. Column Level VPD

Similar to row level enforcement, VPD can be enforced at the column level also. It behaves in the same way but only when the specified columns are selected. The policy would not be activated if the specified columns are not queried or included in the SELECT statement.

The column specification has to be made in the DBMS_RLS package at the same time when policy function is aligned with the database table. The parameter ‘sec_relevant_cols’ accepts the list of columns to be protected under the Policy.

6.1. Define the policy EMP_COL_LOCATION. Note that LOCATION column has been secured with the policy F_LOC_POLICY against SELECT and DMLs.

Sample Code
  1. BEGIN
  2. DBMS_RLS.add_policy
  3. (object_schema => 'SCOTT',
  4. OBJECT_NAME => 'EMPLOYEES',
  5. policy_name => 'EMP_COL_LOCATION',
  6. function_schema => 'SCOTT',
  7. POLICY_FUNCTION => 'F_LOC_POLICY',
  8. STATEMENT_TYPES => 'SELECT, UPDATE, INSERT',
  9. sec_relevant_cols => 'LOCATION' );
  10. END;
Copyright exforsys.com


6.2. Query the EMPLOYEES table without ‘*’ or LOCATION as a selectable

Sample Code
  1. SQL> SELECT EMPNAME FROM employees;
  2.  
  3. EMPNAME
  4. --------------------
  5. John
  6. Kate
  7. Miller
  8. Andy
  9. Mac
  10. Dan
  11. Philip
  12.  
  13. 7 rows selected.
Copyright exforsys.com


6.3. Now select employee name along with their location. The query will be VPD protected.

Sample Code
  1. SQL> SELECT EMPNAME, LOCATION FROM employees;
  2.  
  3. EMPNAME              LOCAT
  4. -------------------- -----
  5. John                 GER
  6. Kate                 GER
Copyright exforsys.com


7. Policy Metadata

The below data dictionary views hold the necessary information about the policies enforced upon the user.

  1. [ALL | USER]_POLICIES – The view contains the complete specification of a Policy. It holds the information of the policy function, protected SQL statements, and policy type information.
  2. [ALL | USER]_POLICY_GROUPS – Maintains the association of a Policy group with the object.
  3. [ALL | USER]_POLICY_CONTEXTS – Maintains the association of a Context with an object.

The DBA maintains the view V$VPD_POLICY to store the information about the policy function and its owner details.

Ads

8. Conclusion

The tutorial lists the VPD implementation in Row and Column level. Besides the individual policies, policy groups can also be declared with many more utilities. One of the most interesting facts is that the Explain Plan for the VPD protected queries shows the VPD predicate and also follows the indexing guidelines available for the query.

Hope the tutorial drives the readers to try their hands out in VPD implementation and use to impose application security.



 
This tutorial is part of a Oracle 11g Tutorial tutorial series. Read it from the beginning and learn yourself.

Oracle 11g Tutorial

 

Comments