分享
 
 
 

现实问题的细粒度审计,第3部分

王朝other·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

在本系列的前两个部分中,我向您介绍了细粒度审计 (FGA) 的概念,它用来在 Oracle9i Database 和更高版本中跟踪选定的语句。我还说明了如何在复杂的环境中(比如说在一个 Web 应用程序内部)通过应用程序上下文和客户端标识符来使用这个特性。这两篇文章为您提供了足够的信息,使您可以为几乎所有类型的数据库系统(无论它有多复杂)构建一个 FGA 设置程序。在这个第三部分,同时也是最后一部分中,我将说明 Oracle Database 10g 为表带来的 FGA 增强。

Oracle9i Database 中的 FGA

让我们简要地重述一下 FGA 的好处。关于完整的讨论,请参考本系列的第 1 部分和第 2 部分。

正规审计(通过 AUDIT 语句)记录使用的语句 ― 如 SELECT 或 INSERT ― 以及谁发出它、从哪一个终端、什么时候等等。然而,信息最重要的部分 ― 哪条特定记录被修改了,以及数据本身的变化 ― 没有捕获到。相反,许多用户编写触发器来捕获变化前后的数据值,并把它们记录在用户自定义的表中。但因为触发器只可能在 DML 语句(如 insert、update 和 delete)上使用,所以访问的一个主要的方面 ― SELECT 语句 ― 不能通过这种途径来审计。

因此 FGA 的价值在于:它只捕获 SELECT 语句。与触发器和 Log Miner 工具一起,FGA 提供了一种机制来审计各种类型的值修改和不涉及到修改的数据访问。

FGA 不仅填补了审计 SELECT 语句的空白,而且还提供了其它的一些引人注目的额外好处,这些好处使得数据库管理员的工作变得更加轻松。例如,FGA 允许一个用户自定义的过程在指定的审计条件出现的时候执行,因此您可以认为它是 SELECT 语句上的一个触发器 ― 这是一个在其它方式下没有提供的功能。这个技巧可能非常有用 ― 例如,任何时候当有人选择了收入超过 1 百万美元的员工的工资记录时,发送一封邮件给一个安全审计员,以在用户自定义的表中生成审计记录,这些表可以不受限制地进行处理(这与 SYS 拥有的 FGA_LOG$ 表不同);利用审计线索识别数据访问类型,以找出最可能的索引机制等等。

由于这些及其它的原因,FGA 成为数据库管理员工具箱中最重要的工具之一。不过,在 Oracle9i Database 中,它缺少一个重要的特性:在 SELECT 语句之外的语句上使用。

所有类型的 DML

在 Oracle Database 10g 中,FGA 已变得很完善 ― 它可以审计所有类型的 DML 语句,而不只是 SELECT。

让我们看一个例子。在本系列的第 1 部分中,我介绍了一个名称为 ACCOUNTS 的表。在那个表上定义的 FGA 策略为:

begin

dbms_fga.add_policy (

object_schema

= 'BANK',

object_name

= 'ACCOUNTS',

policy_name

= 'ACCOUNTS_ACCESS',

audit_column

= 'BALANCE',

audit_condition = 'BALANCE = 11000'

);

end;

在 Oracle 9i Database 下,这个策略只能审计 SELECT 语句。然而,在 Oracle Database 10g 中,您可以扩展它,使它包含 INSERT、UPDATE 和 DELETE。您可以通过指定一个新的参数来实现这个目的:

statement_types = 'INSERT, UPDATE, DELETE, SELECT'

这个参数将在所有包括的语句类型上启用审计。您甚至可能考虑为每种语句类型创建单独的策略,这将允许您随意地启用和禁用策略 ― 尤其是,控制审计线索的创建,以管理它们占用的空间。不过,statement_type 参数默认情况下只审计 SELECT 语句。

在策略中添加新的参数之后,发出以下语句:

update accounts set balance = 1200 where balance = 3000;

这将使一条记录插入到 FGA_LOG$ 表中。注意这条记录是由一个自动事务插入的;即使您回滚 update 语句,这条记录也将存在。您可以从另一个会话来检查线索是否存在。

select lsqltext from fga_log$;

LSQLTEXT

--------------------------------------------------------

update accounts set balance = 3100 where balance = 3000

该行还包括其它所有的相关详细信息(如表名称、策略名称和事务 ID)。

与触发器方法相比较

那么 FGA 能做什么原来的基于触发器的方法不能做的事情?

在 Oracle Database 10g 之前,DML 语句审计是在一个触发器中进行的,类似于以下方式(注意:这不是真实的代码,只是一个代表性的示例):

CREATE TRIGGER XXXXX

ON Table

AFTER INSERT OR UPDATE OR DELETE

FOR EACH ROW

BEGIN

INSERT INTO AUDIT_LOG

Old Value, New Value, Time .....

END

触发器捕获旧的值和新的值,并填充 AUDIT_LOG 表。如果需要,还可以将它变为自动事务。最大的问题是触发器是对每行触发的,而不是每条语句一次。例如,以下语句:

update accounts set balance = 1200 where balance = 3000;

对全部 10,000 条记录触发,在审计表中插入 10,000 行。这种方法可能严重地损害 update 语句的性能,甚至可能因审计线索中的空间问题而导致失败。使用语句触发器也无济于事,因为它不能捕获个别记录的任何新的或旧的值。比较而言,在 FGA 方法中,只创建一条记录,并且插入只在每条语句上执行一次,而不是每行一次 ― 即使有的话,对性能的影响也很小。

在 FGA 中,您可以指定相关的列来限定审计线索仅在这些列被访问时才创建。在触发器中,通过使用触发器定义的 WHERE,这种功能也可以实现。不过,其中存在一个非常重要的差异 ― 在触发器中,只有当列被修改时(而不是被访问时)才检查它们。在 FGA 中,无论何时列被访问(无论它们被修改与否),审计就开始。这个特性使得 FGA 比触发器具有更多的功能。

另一个优点是 FGA 工具的适用性。有时,在一个视图上定义的 INSTEAD OF 触发器在基表上更新视图;另一个 INSTEAD OF 触发器不能捕获由其它的触发器所作的修改,因此这些修改不能被记录。然而,FGA 是建立在视图或表的基础上的,它能够捕获变化,而不论变化来自哪里 ― 用户语句或触发器。

那么,是否存在触发器比 FGA 更好的情况呢?可能有两种情况:

记住,FGA 通过一个自动事务来插入审计线索,这种事务在它自己的上下文中提交。当 DML 语句失败或被回滚时,插入的线索记录不被回滚。如果用户更新了一些东西但没有提交,则不执行修改,但不管怎样,将创建审计线索。这可能导致在审计线索中产生几个虚假的实际项目 ― 一种不希望出现的潜在情况。随后使用通过闪回查询捕获的 SCN 号码对表进行分析将可能揭露这个问题,但这个过程可能非常复杂。但如果这种风险是不可接受的,那么基于触发器的方法将优于 FGA 成为首选。

FGA 记录用户发出的 SQL 语句和 SCN 号码,但不记录在修改之前和之后的值。必须使用一个单独的工具来从表中通过闪回查询取出这些值。因为闪回查询依赖于 UNDO 段中包含的信息(这些信息是有限的),因此这个工具可能不会从过去很久的时间点上取出旧的值。基于触发器的方法在源数据上捕获变化,因此保证旧的值和新的值都有记录。

在变化期间 FGA 的行为

数据始终在变化,因此它有可能变得适用于审计条件 ― 虽然之前它不适用于审计条件,反之亦然。这个问题带来了一些关于 FGA 在不同情况下的行为的有趣问题。考虑我们的例子,其中在 UPDATE 上已经定义了 FGA 策略,条件为 BALANCE = 3000,审计列是 BALANCE。

第 1 种情况

之前:BALANCE = 1000

用户发出:

update accounts set balance = 1200 where ACCOUNT_NO = ....

旧的和新的 balance 都小于 3,000,审计条件不满足;因此这条语句将不会被审计。

第 2 种情况

之前:BALANCE = 1000

用户发出:

update accounts set balance = 3200 where ACCOUNT_NO = ....

新的 balance 大于 3,000,审计条件满足;因此这条语句将 会被审计。

第 3 种情况

之前:BALANCE = 3200

用户发出:

update accounts set balance = 1200 where ACCOUNT_NO = ....

新的 balance 小于 3,000,但旧的 balance 大于 3,000。因此审计条件满足,这条语句将被审计。

第 4 种情况

用户插入一行,其中有 BALANCE

insert into accounts values (9999,1200,'X');

因为 balance 1,200 不满足审计条件,所以这条语句不被审计。如果 balance 列大于或等于 3,000,它将被审计。

第 5 种情况

用户插入一行,其中 balance 的值为空。

insert into accounts (account_no, status) values (9997, 'X');

因为 balance 为空,该列没有任何默认值,所以审计条件不满足(比较 NULL = 3000 结果为 FALSE),这条语句不会被审计。重要注意事项:假设该列有一个大于 3,000 的默认值时,这条语句仍然不会被审计,即使插入行的 balance 列值大于 3000。

所有相关的列?

考虑在表 ACCOUNTS 上定义的一个策略,如下:

begin

dbms_fga.add_policy (

object_schema

= 'ANANDA',

obje

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有