Vpd Virtual Private Database By Saurabh


Published on

1 Like
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Vpd Virtual Private Database By Saurabh

  1. 1. VPD – Virtual Private Database General Overview
  2. 2. VPD - Feature <ul><li>Virtual Private Database offers: </li></ul><ul><ul><li>Lower cost of ownership </li></ul></ul><ul><ul><li>Elimination of the “application security problem” </li></ul></ul><ul><ul><li>Application transparency </li></ul></ul><ul><ul><li>New business opportunities </li></ul></ul><ul><li>VPD Features : </li></ul><ul><ul><li>Partitioned Fine-grained Access Control </li></ul></ul><ul><ul><ul><li>Create unique application contexts per application </li></ul></ul></ul><ul><ul><li>Global Application Context </li></ul></ul><ul><ul><ul><li>Define rules to secure the application </li></ul></ul></ul><ul><ul><li>Oracle Policy Manager </li></ul></ul><ul><ul><ul><li>GUI tool for managing VPD policies </li></ul></ul></ul><ul><ul><li>Support for Synonyms (in 9iR2) </li></ul></ul><ul><ul><li>Support for Column-Level (in 10g) </li></ul></ul><ul><ul><li>Add-on Option: Label Security </li></ul></ul>
  3. 3. <ul><li>Oracle‘s VPD provides access control at the row level. </li></ul><ul><li>It works by appending clauses (predicates) to sql statement executed by the user. To make this happen a Pl/Sql function (policy function) is attached to a table which, when executed, returns a string that will be appended to the sql before it is parsed and executed. </li></ul>Core Concept: Oracle’s Virtual Private Database (VPD) <ul><li>A simple walkthrough of the basic concept.... </li></ul><ul><li>Create a policy function </li></ul><ul><li>FUNCTION employee_policy () </li></ul><ul><li> RETURN VARCHAR2 </li></ul><ul><li>IS </li></ul><ul><li>BEGIN </li></ul><ul><li>RETURN 'locn_ctry = '‘USA''' ; </li></ul><ul><li>END employee_policy ; </li></ul>2 . Attach the employee_function to tbl_employee DBMS_RLS.ADD_POLICY( object_schema => ‘SRC_TSYS_DBA' , object_name => 'TBL_EMPLOYEE' , policy_name => 'VPD_POLICY' , function_schema => ‘SRC_PRIVATE_DBA' , policy_function => 'EMPLOYEE_POLICY' , statement_types => 'SELECT' ); <ul><ul><li>3. Perform SELECT statement </li></ul></ul><ul><ul><li>User Submits: SELECT * FROM tbl_employee </li></ul></ul><ul><ul><li>DB parses/executes: SELECT * FROM tbl_employee WHERE locn_ctry = ‘USA‘ </li></ul></ul>
  4. 4. VPD continued….. <ul><li>User Specific Criteria </li></ul><ul><li>A more realistic application of the previous example would require changing the country depending on the user. </li></ul><ul><li>This requires always knowing the users id from within the database regardless of which db account is in use. This information is not available where the user makes access through connection pools within the middle tier based on the front end user account. </li></ul><ul><li>To overcome this Oracle provides the Client Identifier. </li></ul><ul><li>Client Identifier </li></ul><ul><li>The client identifier is a 64 character string that can be defined to uniquely identify the user currently using the connection. Before a connection can be obtained from the connection pool the client identifier must be set correctly. </li></ul><ul><ul><li>It is unique to a session and stays in the memory attached to that session as long as the session is active. </li></ul></ul><ul><ul><li>The current value of the Client Identifier can be viewed using </li></ul></ul><ul><ul><li>Set the Client Identifier and check it for yourself: </li></ul></ul><ul><ul><li>1. exec dbms_session . set_identifier ( sys_context ( 'USERENV' , 'OS_USER' ) || ' ' || SYSTIMESTAMP ); </li></ul></ul><ul><ul><li>2.SELECT sys_context ( 'USERENV' , 'CLIENT_IDENTIFIER' ) FROM dual </li></ul></ul>
  5. 5. VPD continued….. <ul><li>Although the Client Identifier provides a means of identifing the user, it does not solve the issue of applying user specific criteria to SELECT statements. </li></ul><ul><li>To get over this limitation we use the Application Context </li></ul><ul><li>Application Context </li></ul><ul><li>Application contexts are akin to session variables. Once set, they can be accessed in a session any time. A different value can be set in another session and the values will not be visible across the sessions (as long as the db user is different). However, if the same db user (front end login) is used the changes will be visible across sessions. </li></ul><ul><li>A context has attributes, similar to the columns of a table. </li></ul><ul><li>The attributes of contexts can be defined at runtime. </li></ul><ul><li>To insert a value into the context you use the following command. </li></ul><ul><li>  > DBMS_SESSION.SET_CONTEXT ( context, key, value, user, clientIdentifier ); </li></ul><ul><li>Back to generating user specific Select criteria… </li></ul><ul><li>So, assuming we have a procedure, which is executed upon login to build the users context. Then the policy function can be simplfied to:  </li></ul><ul><li>FUNCTION employee_policy () </li></ul><ul><li>RETURN VARCHAR2 </li></ul><ul><li>IS </li></ul><ul><li>BEGIN </li></ul><ul><li>RETURN 'locn_ctry = sys_context(''VPD_CONTEXT'', ''LOCN'')' ; </li></ul><ul><li>END employee_policy ; </li></ul><ul><li>This provides us with a user based result. </li></ul>
  6. 6. How it comes together... <ul><li>Logging In </li></ul><ul><li>Authenticate the user </li></ul><ul><li>Construct the Client Identifier </li></ul><ul><li>Initialise the application context ( the context must contain the information required to fulfill the policy function requests ) </li></ul><ul><li>Policy Function Execution </li></ul><ul><li>Execute Select - </li></ul><ul><li>Oracle parses sql and scan the sql for tables that have policies attached </li></ul><ul><li>For each table with a policy the policy function will be called. This function returns a predicate that Oracle cleverly appends to the sql. The context is necessary to resolve these predicates. </li></ul><ul><li>Results sent to user </li></ul>The VPD framework is triggered at two specific points in the lifetime of a session. Firstly upon login and secondly when a select statement is submitted. This corresponds to the creation of the user Application Context at login time and the addition of the predicates when a select is executed. <ul><li>Predicates </li></ul><ul><li>To meet our performance needs we have chosen to user static predicates. That is, they will be fired once and meet the restriction requirements for all users. </li></ul><ul><li>Genaral predicate rules: </li></ul>
  7. 7. How it comes together.....continued <ul><li>General Predicate Rules within the Access Model: </li></ul><ul><ul><li>Check if table belongs to a data segment </li></ul></ul><ul><ul><li>If so, check what access the user has to the data segment </li></ul></ul><ul><ul><li>Filter the result set according to the allowed populations </li></ul></ul><ul><ul><li>Check which Dimensions apply </li></ul></ul><ul><ul><li>Get users allowed values for the applicable dimensions </li></ul></ul><ul><ul><li>Filter the result set according to the dimension values. </li></ul></ul><ul><li>If anything goes wrong return nothing. </li></ul><ul><li>A typical predicate… </li></ul><ul><ul><li>((SYS_CONTEXT(‘VPD_CONTEXT’, ‘LOCATION_FLAG’) = ‘ALL’) </li></ul></ul><ul><ul><li>OR </li></ul></ul><ul><ul><li>(SYS_CONTEXT(‘VPD_CONTEXT’, ‘LOCATION_FLAG’) = ‘NONE’) </li></ul></ul><ul><ul><li>AND tbl_vpd_empl_xref.empl_id <> tbl_vpd_empl_xref.empl_id) OR </li></ul></ul><ul><ul><li>(SYS_CONTEXT(‘VPD_CONTEXT’, ‘LOCATION_FLAG’) = ‘I’ AND LOCN_CTRY IN (select generic_id from tbl_dimension_values where user_profile_DIMENSION_ID = SYS_CONTEXT(‘VPD_CONTEXT’,‘LOCATION’)) OR (SYS_CONTEXT(‘VPD_CONTEXT’, ‘LOCATION_FLAG’) = ‘E’ AND LOCN_CTRY NOT IN (select generic_id from tbl_dimension_values where user_profile_DIMENSION_ID = SYS_CONTEXT(‘VPD_CONTEXT’,‘LOCATION’))) </li></ul></ul>
  8. 8. RLS In-Depth <ul><li>The preceding example can help you get started, but there is much more to RLS than this. The security policies can be much more complex, and the policy functions typically return dramatically different strings based on user authorizations. </li></ul><ul><li>DBMS_RLS Package </li></ul><ul><li>Syntax: </li></ul><ul><li>DBMS_RLS.ADD_POLICY ( </li></ul><ul><ul><li>object_schema IN VARCHAR2 NULL, </li></ul></ul><ul><ul><li>object_name IN VARCHAR2, </li></ul></ul><ul><ul><li>policy_name IN VARCHAR2, </li></ul></ul><ul><ul><li>function_schema IN VARCHAR2 NULL, </li></ul></ul><ul><ul><li>policy_function IN VARCHAR2, </li></ul></ul><ul><ul><li>statement_types IN VARCHAR2 NULL, </li></ul></ul><ul><ul><li>update_check IN BOOLEAN FALSE, </li></ul></ul><ul><ul><li>enable IN BOOLEAN TRUE, </li></ul></ul><ul><ul><li>static_policy IN BOOLEAN FALSE, </li></ul></ul><ul><ul><li>policy_type IN BINARY_INTEGER NULL, </li></ul></ul><ul><ul><li>long_predicate IN BOOLEAN FALSE, </li></ul></ul><ul><ul><li>sec_relevant_cols IN VARCHAR2, </li></ul></ul><ul><ul><li>sec_relevant_cols_opt IN BINARY_INTEGER NULL </li></ul></ul><ul><ul><li>) </li></ul></ul><ul><li>New In 10g: </li></ul><ul><li> policy type, long_predicate, </li></ul><ul><li> sec_relevant_cols, and sec_relevant_cols_opt </li></ul><ul><li>Other DBMS_RLS Procedures (Not Covered in this presentation) </li></ul><ul><ul><li>CREATE_POLICY_GROUP </li></ul></ul><ul><ul><li>ADD_GROUPED_POLICY </li></ul></ul><ul><ul><li>ADD_POLICY_CONTEXT </li></ul></ul><ul><ul><li>DELETE_POLICY_GROUP </li></ul></ul><ul><ul><li>DROP_GROUPED_POLICY </li></ul></ul><ul><ul><li>DROP_POLICY_CONTEXT </li></ul></ul><ul><ul><li>ENABLE_GROUPED_POLICY </li></ul></ul><ul><ul><li>DISABLE_GROUPED_POLICY </li></ul></ul><ul><ul><li>REFRESH_GROUPED_POLICY </li></ul></ul>
  9. 9. RLS In-Depth ..(Cont) <ul><li>The PL/SQL functions are registered to tables, views, or synonyms by invoking the DBMS_RLS.ADD_POLICY procedure. The DBMS_RLS package is not granted to everyone; administrators will require direct execute privileges on the package. The ADD_POLICY procedure requires, at minimum, the name of the object to which the policy will be applied, a name for the policy, and the name of a PL/SQL function that will implement the security policy. </li></ul><ul><li>Creating A Policy Function – e.g. CREATE OR REPLACE FUNCTION dept_only ( </li></ul><ul><ul><ul><li>p_schema IN VARCHAR2 DEFAULT NULL, </li></ul></ul></ul><ul><ul><ul><li>p_object IN VARCHAR2 DEFAULT NULL) </li></ul></ul></ul><ul><ul><ul><li> RETURN VARCHAR2 </li></ul></ul></ul><ul><ul><ul><li>AS </li></ul></ul></ul><ul><ul><ul><li>BEGIN </li></ul></ul></ul><ul><ul><ul><li> RETURN 'deptno = sys_context(''people_ctx'',''deptno'')'; </li></ul></ul></ul><ul><ul><ul><li>END; </li></ul></ul></ul><ul><li>Applying the Insert/Update Policy – e.g. BEGIN </li></ul><ul><ul><li> DBMS_RLS.add_policy </li></ul></ul><ul><ul><ul><ul><ul><li>(object_schema => 'SCOTT', </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>object_name => 'PEOPLE', </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>policy_name => 'PEOPLE_IU', </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>function_schema => 'SEC_MGR', </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>policy_function => 'Dept_Only', </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>statement_types => 'INSERT,UPDATE', </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>update_check => TRUE); </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li> END; </li></ul></ul></ul></ul></ul><ul><ul><li>Hence </li></ul></ul><ul><ul><li>update people set ename = '<NEW_VALUE>' will be effectively transformed into </li></ul></ul><ul><ul><li>update people set ename = '<NEW_VALUE>' where deptno = sys_context('people_ctx','deptno') </li></ul></ul>
  10. 10. RLS In-Depth ..(Cont) <ul><li>Delete RLS Policy – The delete policy says that the user can only delete their record </li></ul><ul><ul><ul><ul><ul><li>e.g. CREATE OR REPLACE FUNCTION user_only ( </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li> p_schema IN VARCHAR2 DEFAULT NULL, </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>p_object IN VARCHAR2 DEFAULT NULL) </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>RETURN VARCHAR2 </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>AS </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>BEGIN </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li> RETURN 'username = sys_context(''userenv'',''session_user'')'; </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>END; </li></ul></ul></ul></ul></ul><ul><ul><li>Hence </li></ul></ul><ul><ul><li>DELETE FROM people; will be effectively transformed into </li></ul></ul><ul><ul><li>DELETE FROM people where username = sys_context(''userenv'',''session_user'') </li></ul></ul><ul><li>Viewing the Original SQL and Predicate – The View you may find helpful in inspecting your VPD implementations is the V$VPD_POLICY view. This will tell you what policies have been successfully applied to your SQL statements. The PREDICATE column will actually show the SQL string that was appended to the query. You can join this record with V$SQL, which has the original SQL. </li></ul><ul><ul><li>e.g. > SELECT object_owner, </li></ul></ul><ul><ul><li> object_name, </li></ul></ul><ul><ul><li> policy, </li></ul></ul><ul><ul><li> sql_fulltext, </li></ul></ul><ul><ul><li> predicate </li></ul></ul><ul><ul><li>FROM v$vpd_policy p, v$sql s </li></ul></ul><ul><ul><li>WHERE p.sql_id = s.sql_id </li></ul></ul><ul><ul><li>AND predicate IS NOT NULL; </li></ul></ul><ul><ul><li>OBJECT_OWNER OBJECT_NAME POLICY SQL_FULLTEXT PREDICATE </li></ul></ul><ul><ul><li>------------ ------------ ------ -------------------------- ------------ </li></ul></ul><ul><ul><li>SAURABH EMP DEBUG SELECT COUNT (*) FROM emp ename = user </li></ul></ul><ul><ul><li>PS: No records are recorded if the policy throws an error </li></ul></ul>
  11. 11. Bypassing Security <ul><li>RLS Exemption i.e. EXEMPT ACCESS POLICY – </li></ul><ul><li>1. While the RLS provides wonderful security, it can be problematic when doing database administration tasks such as performing data backups. As you have seen, even the DBAs and the data owner cannot bypass the RLS policy. If you perform an export as the data owner or another administrator while an RLS policy was enabled, you may very well end up with a dataless backup file. For this reason (and a few others), there is an EXEMPT ACCESS POLICY privilege </li></ul><ul><ul><ul><ul><ul><li>e.g. </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>SQL>DELETE FROM scott.people_ro; </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>SQL> 0 rows deleted. </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>SQL> GRANT EXEMPT ACCESS POLICY TO SYSTEM; </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>SQL>Grant succeeded. </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>SQL>DELETE FROM scott.people_ro; </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>SQL>14 rows deleted. </li></ul></ul></ul></ul></ul><ul><li>2. The system privilege EXEMPT ACCESS POLICY allows a user to be exempted from all fine-grained access control policies on any DML operation such as SELECT, INSERT, UPDATE, and DELETE. If a user is granted the EXEMPT ACCESS POLICY privilege, then the user is exempt from fine-grained access control enforcement. then the user is exempt from fine-grained access control enforcement. </li></ul><ul><li> e.g. grant exempt access policy to gtsup; </li></ul>
  12. 12. Implications of VPD for developers.... <ul><li>Adding new tables </li></ul><ul><ul><li>Does it contain sensitive data ? should VPD be applied. </li></ul></ul><ul><ul><li>If yes, consider the analysis required to arrive at the predicates. </li></ul></ul><ul><li>User Profile Issues </li></ul><ul><ul><li>It is possible for a user to have multiple profiles within Access. These profiles will be provisioned differently and may or may not have access to Production instances. </li></ul></ul><ul><ul><ul><li>eg. IT_Developer and IT_Support </li></ul></ul></ul><ul><ul><ul><li>How to switch between profiles ? </li></ul></ul></ul>
  13. 13. Summary <ul><li>Virtual Private Database (VPD) helps resolve some of the challenges associated with views. An RLS policy is defined as a mapping from a PL/SQL implemented security function to a table, view, or synonym. </li></ul><ul><li>To ensure high performance, the RLS mechanism has been written to modify the SQL before it is parsed and executed. This allows the database to use indexes and optimization plans to ensure fast access to data. Using bind variables and application contexts and enabling policy caching can significantly improve RLS performance. </li></ul><ul><li>Project : Please check out a dummy project at : http://www.psoug.org/reference/fgac_demo.html </li></ul>