直接grant update on sys.aud$给非sys用户极危险,因aud$存储所有审计记录,授权等于赋予其篡改或删除日志权限,可掩盖违规操作,导致等保不合规;应通过fga拦截dml、使用只读视图dba_audit_trail及统一审计替代传统aud$。

为什么直接 GRANT UPDATE 给 AUD$ 是危险的
Oracle 的标准审计表 AUD$ 由 SYS 拥有,且默认只允许 SYS 或启用 AUDIT_ADMIN 角色的用户写入。但很多 DBA 为方便开发查日志,会执行类似 GRANT SELECT, UPDATE ON SYS.AUD$ TO dev_user —— 这等于把审计日志的“橡皮擦”交到了开发手上。一旦被滥用,DELETE FROM SYS.AUD$ WHERE TIMESTAMP# > SYSDATE - 7 就能抹掉一周操作痕迹,等保测评直接一票否决。
用细粒度访问控制(FGA)拦截对 AUD$ 的 DML
Oracle 不允许对 SYS.AUD$ 创建 DML 触发器(会报 ORA-04089),但 FGA 支持对任何表(包括 SYS 下对象)定义策略,并在 DML 执行前触发自定义逻辑。关键在于:FGA 策略本身不阻止操作,但可配合存储过程抛出异常中断事务。
- 创建拦截函数:
CREATE OR REPLACE FUNCTION audit_dml_blocker(p_schema VARCHAR2, p_obj VARCHAR2) RETURN VARCHAR2 IS BEGIN RAISE_APPLICATION_ERROR(-20001, 'DML on SYS.AUD$ is prohibited'); END; - 绑定 FGA 策略:
BEGIN DBMS_FGA.ADD_POLICY( object_schema => 'SYS', object_name => 'AUD$', policy_name => 'block_aud_dml', audit_condition => '1=1', audit_column => NULL, handler_schema => 'SYS', handler_module => 'audit_dml_blocker' ); END; - 该策略对所有 DML(INSERT/UPDATE/DELETE)生效,且无需重启数据库
替换 AUD$ 为只读视图 + 审计日志专用账号
真正安全的做法不是“防不住就拦”,而是“根本看不到原始表”。让开发人员只通过受控视图访问审计数据,同时隔离权限边界:
- 新建只读账号:
CREATE USER audit_reader IDENTIFIED BY "StrongPass123!"; - 授权最小权限:
GRANT SELECT ON DBA_AUDIT_TRAIL TO audit_reader;(注意:不用SYS.AUD$,而用视图封装) - 创建带过滤的视图:
CREATE VIEW audit_reader.v_audit_recent AS SELECT timestamp#, username, action_name, sql_text FROM dba_audit_trail WHERE timestamp# > SYSDATE - 30; - 禁止该账号连接
SYS:ALTER USER audit_reader SET CONTAINER_DATA = NONE CONTAINER=CURRENT;(多租户环境)
统一审计(Unified Audit)下如何彻底禁写
如果已启用 Oracle 12c+ 的统一审计(AUDIT_UNIFIED_ENABLED),AUD$ 不再使用,审计记录写入 UNIFIED_AUDIT_TRAIL(基于外部表或 OS 文件)。此时真正的防护点是文件系统权限和目录对象控制:
- 确认统一审计路径:
SELECT parameter_value FROM v$unified_audit_trail_parameters WHERE parameter_name = 'UNIFIED_AUDIT_TRAIL'; - 若为
OS类型,确保unified_audit_file_dest目录仅oracle用户可写,且开发账号无READ权限(Linux 下chmod 750+chown oracle:oinstall) - 若为
DB类型,UNIFIED_AUDIT_TRAIL是只读数据字典视图,底层表AUD$UNIFIED无法被普通用户直接访问,连SELECT都需UNIFIED_AUDIT_TRAIL权限,更别说 DML
最易被忽略的是:即使启用了统一审计,旧的 AUD$ 表仍可能存在残留数据,且未显式禁用传统审计时,它仍会被写入。必须运行 NOAUDIT ALL; 并确认 AUDIT_TRAIL 参数设为 NONE 或 DB,EXTENDED(非 OS)后,再迁移策略到统一审计体系。











