DBMS_SESSION.SET_CONTEXT的使用及无效权限问题的解决

ORA-01031: insufficient privileges
ORA-06512: at "SYS.DBMS_SESSION", line 90
ORA-06512: at "UNIFLOW.SET_MY_APP_CTX", line 5
ORA-06512: at line 1

应用程序环境

使用客户端标识符有它的优点,但也存在严重的安全威胁:这种设置假定用户将值设为真正的用户 id,但这一点无法得到保证。恶意攻击的用户可以连接然后将该值设为不同的用户 id,严重地破坏审计跟踪的真实性。在 web 应用程序中,使用 cookie 存储客户端标识符使得破坏更困难(如果不是不可能);但是在普通的应用程序中,仅仅使用客户端标识符,安全性可能不尽人意。我们需要一种更安全的方法来捕获审计跟踪中的应用程序用户。

进入解决方案:应用程序环境.应用程序环境类似于会话变量;一旦设置了,任何时候都可以在会话中访问它们。可以在另一个会话中设置一个不同的值,而在整个会话中都看不到这个值。环境具有的属性类似于表的列;但与表不同的是,环境不是片段对象,属性可以在运行时而不是设计时定义。

可以使用下列 SQL 创建应用程序环境:

create context my_app_ctx using set_my_app_ctx;

注意,子句 using set_my_app_ctx 意味着环境中的属性只能通过名为 set_my_app_ctx 的过程来操作,该过程定义如下:

create or replace procedure set_my_app_ctx
(
   p_app_user in varchar2 := USER
)
is
begin
   dbms_session.set_context('MY_APP_CTX','APP_USERID', p_app_user);
end;

此过程通过调用 dbms_session.set_context API,简单地将属性 APP_USERID 设置为输入参数传递的值。因此,如果用户直接调用此 API,其结果会如何呢?

SQL> exec dbms_session.set_context('MY_APP_CTX','APP_USERID', 'JUNE')
BEGIN dbms_session.set_context('MY_APP_CTX','APP_USERID', 'JUNE'); END;

*
ERROR at line 1:
ORA-01031: insufficient privileges
ORA-06512: at "SYS.DBMS_SESSION", line 78
ORA-06512: at line 1

注意错误 ORA-01031:insufficient privileges 有点令人误解。用户的确对 SYS.DBMS_SESSION 有执行权限,但是通过调用它来设置环境属性是违法的,因此出现了错误。但是,当用户调用受信任的过程来设置环境属性:

SQL> execute set_my_app_ctx ('AAAA')

PL/SQL procedure successfully completed.

设置成功了。因为环境属性只能通过它的过程(正确叫法是 受信任的过程)来设置。这是应用程序环境一个非常重要的属性,将在 FGA 中得到使用。

一旦设置了环境属性,可以通过调用函数 SYS_CONTEXT 来检索它。在上述代码中设置完环境后,可以通过下列语句来查看环境:

select sys_context('MY_APP_CTX','APP_USERID') from dual;

该语句返回属性值。如果可以通过安全的方式设置环境,则可以利用环境来设置客户端标识符。

基于我们现有的知识,以下是可能的解决方案:

  • 应用程序执行过程代码,该代码自动地将应用程序环境设置为正确的值。在上述示例中,使用了用户 id 的环境属性,但另一个属性—如用户的角色—可能已经被使用了。可以在一个环境中定义多个属性。可以将属性作为启用的角色使用。受信任的过程可以包括各种类型的安全检查,从而使得它安全且真实可信。如果安全检查失败了,则不能设置所需的角色。因此,即使用户可以使用 APPUSER 帐号成功地登录,他也不能够操作数据,因为没有启用适当的角色。注意,角色必须经过过程认证,而不能是普通的角色。这种角色由命令 CREATE ROLE <role_name>USING <procedure_name></procedure_name></role_name>创建;用户通过调用 <procedure_name></procedure_name>而不是 SET ROLE 命令启用角色。

  • 此过程也设置客户端标识符,因此没有必要授予公众对 dbms_session 的执行权限,即使对此用户也没有必要。由于用户没有权限调用 API,他们不能直接设置客户端标识符—客户端标识符将被自动设置,并且传递到细粒度的审计跟踪。

你可能感兴趣的:(sql)