先查拥有DBA角色的非SYS/SYSTEM用户:SELECT grantee, admin_option, default_role FROM dba_role_privs WHERE granted_role='DBA' AND grantee NOT IN ('SYS','SYSTEM');重点回收ADMIN_OPTION='YES'者,执行REVOKE DBA FROM username,并用细粒度权限替代,同时检查残留GRANT ANY PRIVILEGE。

查谁有 DBA 角色,先砍掉最危险的权限链
DBA 角色不是“功能开关”,而是近 200 个系统权限的集合体,包含 ALTER SYSTEM、DROP USER、GRANT ANY PRIVILEGE 等高危权限。只要用户被授予 DBA,且带有 WITH ADMIN OPTION,就可能把权限再分发出去,形成失控链。
执行以下查询确认风险面:
SELECT grantee, admin_option, default_role
FROM dba_role_privs
WHERE granted_role = 'DBA' AND grantee NOT IN ('SYS', 'SYSTEM');重点关注 ADMIN_OPTION = 'YES' 的行——这类用户能再授 DBA,必须立即回收:
- 用
REVOKE DBA FROM username直接移除角色 - 若业务真需要部分管理能力,改用细粒度系统权限替代(如只给
CREATE SESSION+SELECT ANY DICTIONARY) - 回收后务必检查
DBA_SYS_PRIVS,确认没残留GRANT ANY PRIVILEGE这类“权限之权限”
识别长期未使用的权限,别让“以防万一”变成漏洞温床
Oracle 不记录“谁用过什么权限”,但能通过审计线索反推活跃度。如果没开标准审计,至少可查最近 7 天的会话级对象访问痕迹:
SELECT DISTINCT owner, object_name, object_type
FROM dba_hist_active_sess_history a
JOIN dba_objects o ON a.current_obj# = o.object_id
WHERE a.sample_time > SYSDATE - 7
AND a.user_id != 0 -- 排除 SYS
AND o.owner NOT IN ('SYS', 'SYSTEM');结果里没出现的表、视图、包,大概率是闲置对象。对应授予的 SELECT、EXECUTE 权限就可以清理。
- 不要直接删权限,先用
REVOKE ... FROM username回收,观察 2–3 个工作日是否报错 - 特别注意
SELECT ANY TABLE和SELECT_CATALOG_ROLE:它们绕过对象级授权检查,极易被滥用 - 若用户只读特定几张表,就只给那几张表的
SELECT,别用SELECT ANY TABLE图省事
用 Data Safe 自动识别权限过载用户
Oracle Data Safe 是唯一能自动打分“权限风险值”的内置工具。它不只看权限数量,还会结合用户类型(普通用户/应用账号)、密码策略、最近登录时间、是否启用 MFA 等维度建模。
在云环境或 19c+ 本地库中启用后,运行评估:
EXEC DBMS_DATA_SAFE.ANALYZE_USER_PRIVILEGES;
然后查报告:
SELECT username, risk_score, high_risk_reasons FROM dba_users_with_privs WHERE risk_score > 70;
常见高分原因包括:UNLIMITED TABLESPACE + CREATE PROCEDURE + 密码未过期。这类组合允许用户创建恶意 PL/SQL 并写入任意表空间,必须拆解。
-
UNLIMITED TABLESPACE改为具体配额,如QUOTA 500M ON users -
CREATE PROCEDURE改为仅在开发 PDB 中开放,生产环境禁用 - 对风险分 > 85 的用户,强制启用 Oracle Wallet 或 TDE 加密其连接凭据
迁移/同步场景下最容易漏掉的最小权限项
很多团队在做 OMS 或 GoldenGate 迁移时,习惯性给源端用户 DBA,其实完全没必要。根据 Oracle 官方迁移文档,全量同步阶段真正必需的是:
-
SELECT权限:只针对待迁移的表,不是整个 schema -
SELECTonV_$DATABASE、V_$INSTANCE、DBA_TABLES、DBA_TAB_COLUMNS—— 用于元数据发现 -
SELECTonDBA_MVIEW_LOGS(仅增量需物化日志) - 绝对不要给
SELECT ANY DICTIONARY:它等价于SELECTon 所有DBA_*视图,暴露太多内部结构
一个典型误操作是:为了“兼容旧脚本”,把 oms_user 的默认表空间设为 SYSTEM。这会导致该用户创建的临时对象污染核心字典表空间,后续审计时根本分不清哪些是迁移工具生成的,哪些是攻击者留下的。


















