EBS VPD介绍和使用实例
Posted Jane Chiu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了EBS VPD介绍和使用实例相关的知识,希望对你有一定的参考价值。
VPD介绍
什么是VPD(虚拟专用数据库):
VPD is one feature that allows development community to enforce security by attaching a security policy to database objects such as tables, views and synonyms.
简单的说,VPD就是向特定的数据库对象附加一个安全策略,在对这个对象操作的过程在中,会自动的使用这个安全策略进行验证,同时满足自定义条件和安全策略的操作才会获得预期的结果。下面以一个故事来介绍VPD:
在一个交友网站上,有一张表ALL_PERSON_INFO存放该网站所有帅哥靓女的信息,该表有一个字段gender来存放该记录的性别。当一个用户登录该网站时,系统会有一个session值记录当前用户的性别。同时为了防止该网站背上同性恋之家的黑名,于是站长就来了一条严重的限制,该网站的用户只能查看到异性的信息。当一位名叫Tea的帅哥登录到这个网站,需要查找名字中带有coffee的女性时,常有的查询语句是:
Select * from
ALL_PERSON_INFO api
where api. Gender <>session( ‘gender’)
and api.name like = ‘%coffee%’
很好,该语句查到的永远都是用户的异性信息。
但一个电脑牛人gay却想去看该系统的帅哥信息,他获取到这条查询语句后,使用SQL注入的技术(或其他技术)在该SQL查询上添加了另外一个条件,然后变成如下语句:
Select * from
ALL_PERSON_INFO api
where api. Gender <>session( ‘gender’)
and api.name like = ‘%coffee%’
or api. Gender = session( ‘gender’)
这样造成的结果就是该网站所有的帅哥信息,赤裸裸地被这个gay拿去和他的同类们分享。
于是该网站的站长就气愤地找他们的DBA,说他没有把数据保护好,这下可苦了这个DBA,但却是也不是他的错啊,话虽如此,但系统优化还是得继续。这个DBA开始了他的优化系统之路,通过多方查找,他将视线定位在了VPD上,使用该技术,他成功根除了这个安全隐患。他的基本步骤概括如下:
首先将session( ‘gender’)放到一个APPLICATION CONTEXT中,然后为该表建立了一个同义词GENDER_PERSON_INFO,然后在该同义词上设置了一项安全策略,该策略具有一个相关函数,称为policy function,它返回一个用作谓词的字符串api. Gender <>sys_context(‘friend’,’gender’),通过使用该策略,凡是含有api. Gender = session( ‘gender’)的查询将不会返回任何结果。
VPD使用实例
建立对象和数据
CREATE TABLE hss.vpd_test(
ID NUMBER,
NAME VARCHAR2(100),
gender CHAR(1)
);
INSERT INTO hss.vpd_test VALUES(1,'hansen','M');
INSERT INTO hss.vpd_test VALUES(2,'tea','M');
INSERT INTO hss.vpd_test VALUES(3,'tiger','F');
INSERT INTO hss.vpd_test VALUES(4,'coffee','F');
COMMIT;
查询数据如下:
在APPS下建立同义词
CREATE SYNONYM HX_VPD_TEST For hss.vpd_test;
查询结果如下:
建立应用程序上下文
CREATE CONTEXT HX_VPD USING apps.XXHX_VPD_PKG;
查询结果如下:
建立策略函数包和应用设置函数包,包头定义如下
CREATE OR REPLACE PACKAGE XXHX_VPD_PKG IS
/*==================================================
Program Name:
XXHX_VPD_PKG
Description:
该pakcage的功能是建立策略函数gender_valid,
设置应用程序上下文值
History:
1.00 2016-11-28 Jane Creation
==================================================*/
/*==================================================
Function Name :
gender_valid
Description:
安全策略函数必须带2个参数:第1个参数是方案名
(或用户名)、第2个参数是方案对象名(或表名、
视图名)。该函数返回附加到SQL语句的where子句
后面的字符串.即使在安全策略函数中不使用也要带
上所述2个参数,否则在执行时会出现“ORA-28112:
无法执行策略函数”的错误提示。
Argument:
obj_schame 方案名
obj_name 方案对象名
Return
安全策略字符串
History:
1.00 2016-11-28 Jane Creation
==================================================*/
FUNCTION gender_valid(obj_schame VARCHAR2,
obj_name VARCHAR2) RETURN VARCHAR2;
/*==================================================
Function Name :
set_context
Description:
该方法用于设置应用程序上下文的值
Argument:
p_user_gender 性别
History:
1.00 2016-11-28 Jane Creation
==================================================*/
PROCEDURE set_context(p_user_gender VARCHAR2);
END xxhx_vpd_pkg;
注册为对象注册策略
BEGIN
DBMS_Rls.Add_Policy( object_schema =>'APPS',
object_name =>'HX_VPD_TEST',
policy_name =>'HX_VPD_GENDER',
function_schema => 'APPS',
policy_function =>'XXHX_VPD_PKG.GENDER_VALID',
policy_type => DBMS_RLS.SHARED_CONTEXT_SENSITIVE);
END;
查看结果:
查看策略函数返回的条件
查看使用策略后查看F的结果
查看使用策略后,性别为 M的 结果
但当我们开一个新窗口,再查询的时候就没有结果
MOAC中VPD的使用
查看策略函数
SELECT *
FROM dba_policies DBA
WHERE dba.object_name = 'PO_HEADERS';
结果:
结果分析:
从该结果中可以得到策略函数是MO_GLOBAL.ORG_SECURITY;
查看可能涉及的Application Context:
SELECT *
FROM dba_context dc
WHERE package = 'MO_GLOBAL'
结果:
结果分析:
从该结果中可以得到在MO_GLOBAL.中使用了两个Application Context,但我们不能肯定都是我们需要的,需要进入MO_GLOBAL.ORG_SECURITY函数中检查;
MO_GLOBAL.ORG_SECURITY分析
FUNCTION org_security(obj_schema VARCHAR2,
obj_name VARCHAR2) RETURN VARCHAR2 IS
l_ci_debug fnd_profile_option_values.profile_option_value%TYPE := NULL;
BEGIN
--
-- Returns different predicates based on the access_mode
-- The codes for access_mode are
-- M - Multiple OU Access
-- A - All OU Access
-- S - Single OU Access
-- Null - Backward Compatibility - CLIENT_INFO case --
-- The Predicates will be appended to Multi-Org synonyms
IF obj_name = 'AR_PAYMENT_SCHEDULES' AND g_access_mode = 'S' THEN
RETURN 'org_id = sys_context(''multi_org2'',''current_org_id'') OR (org_id = -3116)';
ELSIF g_access_mode IS NOT NULL THEN
IF g_access_mode = 'M' THEN
RETURN 'EXISTS (SELECT 1
FROM mo_glob_org_access_tmp oa
WHERE oa.organization_id = org_id)';
ELSIF g_access_mode IN ('A', 'B') THEN
RETURN 'org_id <> -3113'; -- Bug5109430 filter seed data from policy predicate
ELSIF g_access_mode = 'S' THEN
RETURN 'org_id = sys_context(''multi_org2'',''current_org_id'')';
ELSIF g_access_mode = 'X' THEN
RETURN '1 = 2';
END IF;
ELSE
-- This section is used reserved for debugging using CLIENT_INFO
-- Interim solution for MFG teams
fnd_profile.get('FND_MO_INIT_CI_DEBUG',
l_ci_debug);
IF l_ci_debug = 'Y' THEN
RETURN 'org_id = substrb(userenv(''CLIENT_INFO''),1,10)';
ELSE
RETURN '1=2';
END IF;
END IF;
END org_security;
分析:
第一个条件
IF obj_name = 'AR_PAYMENT_SCHEDULES' AND g_access_mode = 'S' THEN
RETURN 'org_id = sys_context(''multi_org2'',''current_org_id'') OR (org_id = -3116)';
关于对象AR_PAYMENT_SCHEDULES,在dba_policies表中查看策略函数是GLOBAL.ORG_SECURITY_GLOBAL,对于该方法有段注释This is a restricted policy function to support global data -3116.所以这个条件可以忽略。
第二个条件
IF g_access_mode = 'M' THEN
RETURN 'EXISTS (SELECT 1
FROM mo_glob_org_access_tmp oa
WHERE oa.organization_id = org_id)';
这个条件就是实现多ou的判断条件,如果当前的访问模式是’M’,并且数据的org_id也在session表mo_glob_org_access_tmp中,那么这条数据是安全的。
第三个条件
ELSIF g_access_mode IN ('A', 'B') THEN
RETURN 'org_id <> -3113'; -- Bug5109430 filter seed data from policy predicate
“该 Bug 不是公众可访问的 Bug (未公开)“这是我在metalink上查找Bug5109430的信息,不过有注释表明access _Mode=A是预留到将来使用,我估计access _Mode=B也是为了将来使用。
第四个条件
ELSIF g_access_mode = 'S' THEN
RETURN 'org_id = sys_context(''multi_org2'',''current_org_id'')';
第五个条件
ELSIF g_access_mode = 'X' THEN
RETURN '1 = 2';
返回nothing 不知道有什么用。
接下来使用了一个预制文件’FND_MO_INIT_CI_DEBUG’,我们可以查到他的用处:“MO:设置 Client_Info 以进行调试它的说明是“此配置文件仅限 Oracle 用于调试用途。”
在上面的分析中,我们得出该系统使用了临时表mo_glob_org_access_tmp和上下文sys_context(”multi_org2”,”current_org_id”)的值。也明白了PO_HEADRES查询不到数据的原因,可能是mo_glob_org_access_tmp和上下文sys_context(”multi_org2”,”current_org_id”)的值为空。
初始化环境:
我们知道mo_global.set_policy_context可以设置环境的初始化,如果能将这些理解,完全能够解决PO_HEADERS没有数据的问题,以及类似的问题。
以上是关于EBS VPD介绍和使用实例的主要内容,如果未能解决你的问题,请参考以下文章