必须优先回收public对utl_file、utl_http、utl_tcp、utl_smtp、dbms_random、ctx_doc、dbms_export_extension、dbms_sql的execute权限,因它们可被用于文件读写、网络外连、代码注入等高危攻击;严禁直接撤销select any table,否则将导致standard包失效、大量对象invalid及ora-06553错误。
直接撤销 public 的默认权限不是加固,而是高风险操作;盲目执行 revoke 可能导致 standard 包失效、大量对象变 invalid、应用报 ora-06553,甚至数据库无法登录。
哪些 EXECUTE 权限必须优先回收
Oracle 官方明确建议从 PUBLIC 撤销以下高危包的执行权限,因为它们可被任意用户用于文件读写、网络外连、代码注入等攻击链:
-
UTL_FILE:读写数据库服务器本地文件系统 -
UTL_HTTP、UTL_TCP、UTL_SMTP:发起任意 HTTP/TCP/SMTP 请求,常被用于 SSRF 或反向 shell -
DBMS_RANDOM:虽看似无害,但配合其他漏洞可辅助预测或绕过逻辑校验 -
CTX_DOC、DBMS_EXPORT_EXTENSION、DBMS_SQL:历史上存在多个提权 CVE,非必要不开放
执行示例(需 SYSDBA):
REVOKE EXECUTE ON sys.utl_file FROM PUBLIC; REVOKE EXECUTE ON sys.utl_http FROM PUBLIC; REVOKE EXECUTE ON sys.utl_tcp FROM PUBLIC;
注意:REVOKE 语句中必须显式指定 schema(通常是 sys),否则会报 ORA-00942: table or view does not exist。
为什么不能直接 REVOKE SELECT ANY TABLE FROM PUBLIC
这是最易踩坑的操作。一旦执行:
REVOKE SELECT ANY TABLE FROM PUBLIC;
所有依赖数据字典视图的内置包(如 STANDARD、DBMS_STANDARD)将立即变为 INVALID,后续任何 PL/SQL 编译或登录都可能失败,典型错误是:
ORA-06553: PLS-213: STANDARD package not accessible
这不是 bug,而是 Oracle 的设计机制:很多核心包在编译时隐式引用了 ALL_* 或 DBA_* 视图,而这些视图依赖 SELECT ANY TABLE 授权链。
验证方式:
- 先查是否真有该授权:
SELECT * FROM DBA_SYS_PRIVS WHERE GRANTEE = 'PUBLIC' AND PRIVILEGE = 'SELECT ANY TABLE'; - 若存在,不要直接 revoke —— 应改用细粒度授权(如只给特定用户查
V_$SESSION)
撤销前必须做的三件事
跳过任一环节都可能导致不可逆故障:
-
确认权限真实存在:运行
SELECT * FROM DBA_TAB_PRIVS WHERE TABLE_NAME = 'UTL_FILE' AND GRANTEE = 'PUBLIC' AND PRIVILEGE = 'EXECUTE';,无结果就别执行REVOKE,否则报ORA-01927 -
检查依赖对象:用
SELECT OWNER, NAME, TYPE FROM DBA_DEPENDENCIES WHERE REFERENCED_NAME = 'UTL_FILE' AND REFERENCED_OWNER = 'SYS';找出调用该包的过程、函数、包体,重点看状态为INVALID的项 -
留好回退路径:提前备份
DBA_TAB_PRIVS和DBA_SYS_PRIVS快照;测试环境先跑通;生产环境务必在维护窗口内操作,并准备好GRANT回滚语句
真正难的不是写那条 REVOKE,而是判断哪个包还在被某个十年没动过的报表作业调用;权限收得太急,修复成本远高于漏洞本身。











