EBS VPD介绍和使用实例
2016-11-30 00:36
295 查看
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没有数据的问题,以及类似的问题。
相关文章推荐
- Web Service介绍使用及实例-C#.Net
- 实例介绍joomla! xml解析器的使用 【转】
- 监视和截获指定进程网络数据传输WSockExpert0.6 工具介绍和使用实例
- Linux Shell 通配符、元字符、转义符使用实例介绍
- 2011 wireshark 抓包工具 使用说明 实用过滤表达式(针对ip、协议、端口、长度和内容) 实例介绍
- JDK5的ProcessBuilder介绍和使用实例
- Linux Shell 正则表达式之 通配符、元字符、转义符使用实例介绍
- Linux Shell 通配符、元字符、转义符使用实例介绍
- Linux Shell 通配符、元字符、转义符使用实例介绍
- Linux Shell 通配符、元字符、转义符,正则表达式使用实例介绍
- 以实例简单介绍如何使用SVN
- Delphi接口使用实例介绍
- Linux Shell 通配符、元字符、转义符使用实例介绍
- Android中抽屉(SlidingDrawer)的使用介绍及实例记录
- Linux Shell 通配符、元字符、转义符使用实例介绍
- Web Service介绍使用及实例-C#.Net
- Linux Shell 通配符、元字符、转义符使用实例介绍
- Android中抽屉(SlidingDrawer)的使用介绍及实例记录
- 实例介绍如何配置使用 VMControl 多网络支持功能
- Linux Shell 通配符、元字符、转义符使用实例介绍