必须优先回收utl_file、utl_http、utl_tcp、utl_smtp、dbms_random等包的public execute权限,严禁直接revoke select any table from public,否则将导致standard等核心包invalid并引发登录或编译失败。
直接撤销 public 的高危包执行权限是必要动作,但盲目执行 revoke select any table from public 会立即让数据库瘫痪——这不是加固,是自毁。
哪些 EXECUTE 权限必须优先回收
Oracle 官方明确要求从 PUBLIC 撤销以下包的 EXECUTE 权限,它们构成最常见攻击链入口:
-
UTL_FILE:任意用户可读写数据库服务器本地文件系统 -
UTL_HTTP、UTL_TCP、UTL_SMTP:发起外连请求,用于 SSRF 或反向 shell -
DBMS_RANDOM:表面无害,但配合逻辑漏洞可辅助绕过校验 -
CTX_DOC、DBMS_EXPORT_EXTENSION、DBMS_SQL:历史上存在提权 CVE,非业务必需就该关
执行时必须带 schema 前缀:REVOKE EXECUTE ON sys.utl_file FROM PUBLIC;。漏写 sys. 会报 ORA-00942。
为什么不能碰 SELECT ANY TABLE
这是最常踩的坑。一旦执行 REVOKE SELECT ANY TABLE FROM PUBLIC;:
- 所有依赖数据字典视图的内置包(如
STANDARD、DBMS_STANDARD)立刻变INVALID - 后续任何 PL/SQL 编译、甚至用户登录都可能失败,典型错误是
ORA-06553: PLS-213: STANDARD package not accessible - 这不是 bug,而是 Oracle 编译机制决定的:核心包隐式引用
ALL_*/DBA_*视图,而这些视图依赖该权限链
真要限制数据字典访问,应改用细粒度授权,比如只给特定用户查 V_$SESSION,而不是一刀切。
执行前必须验证的三件事
跳过任一环节都可能导致不可逆故障:
- 确认权限真实存在:
SELECT * FROM DBA_TAB_PRIVS WHERE TABLE_NAME = 'UTL_FILE' AND GRANTEE = 'PUBLIC' AND PRIVILEGE = 'EXECUTE';—— 无结果就别执行REVOKE,否则报ORA-01927 - 确认当前用户具备
SYSDBA权限,且连接的是sys用户(非普通用户或SYSTEM) - 检查是否有应用显式依赖这些包(如旧版报表工具调用
UTL_HTTP),若有,需先协调改造或白名单授权
真正难的不是“怎么 revoke”,而是判断哪些权限被谁用了、哪些能关、哪些得留着——这需要结合审计日志、应用清单和最小权限原则做交叉验证,而不是靠一条 SQL 解决所有问题。











