Oracle如何撤销PUBLIC的默认权限_安全加固指南
直接撤销PUBLIC默认权限需分步验证、按包评估并保留回退路径;盲目执行REVOKE可能导致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 错误。
撤销 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_* 这类视图,而这些视图的访问权限链恰恰依赖于 SELECT ANY TABLE。
一旦发生这种情况,补救措施通常只有两种:
- 立即运行
@?/rdbms/admin/utlrp.sql脚本,尝试重新编译所有无效对象(这要求数据库在线,且无法保证100%成功)。 - 如果已经无法登录,那就只剩下从 RMAN 备份恢复,或者冒险重建数据字典(执行
@?/rdbms/admin/catalog.sql和@?/rdbms/admin/catproc.sql),后者的风险极高。
所以,结论非常明确:除非你完全掌控所有应用逻辑,并且能百分百确认没有任何自定义包依赖数据字典,否则,绝对不要轻易去动授予 PUBLIC 的 SELECT ANY TABLE 权限。
如何安全地批量检查与清理
别依赖记忆或者陈旧的文档去猜测——最可靠的方式是用 SQL 语句精确识别当前的安全暴露面。
首先,检查 PUBLIC 目前拥有哪些高危的 EXECUTE 权限:
SELECT table_name, owner FROM dba_tab_privs WHERE grantee = 'PUBLIC' AND privilege = 'EXECUTE' AND table_name IN ('UTL_FILE','UTL_HTTP','UTL_TCP','UTL_SMTP','DBMS_RANDOM');
其次,排查是否有敏感对象被误授给了 PUBLIC:
SELECT owner, table_name FROM dba_tab_privs WHERE grantee = 'PUBLIC' AND privilege = 'SELECT' AND owner NOT IN ('SYS','SYSTEM','XDB','CTXSYS');
在这个过程中,有几个关键点必须牢记:
- 只对那些你明确知晓用途的对象执行
REVOKE,切忌进行无差别的批量操作。 - 每次执行
REVOKE之后,立刻查询SELECT object_name FROM dba_objects WHERE status = 'INVALID',以确认影响范围。 - 生产环境务必在计划好的维护窗口内执行,并提前备份权限快照:
CREATE TABLE public_privs_bak AS SELECT * FROM dba_tab_privs WHERE grantee = 'PUBLIC';。
为什么不能直接删掉 PUBLIC 角色
最后,需要澄清一个常见的误解:PUBLIC 并非普通角色,它是 Oracle 内置的一个隐式组,无法通过 DROP ROLE 或 DROP USER 命令删除。如果试图用 REVOKE CONNECT FROM PUBLIC 或 REVOKE CREATE SESSION FROM PUBLIC 来操作,可能会导致整个数据库无法建立新的会话——连 sqlplus / as sysdba 这样的管理连接都可能失败。
问题的核心在于,我们真正能控制的是“授权的内容”,而不是“角色本身”。安全加固的本质是做减法:只保留对 DUAL、SYSDATE 这类无副作用对象的公共访问权限,其余所有权限,一律按需、显式地授予具体的用户或角色。
还有一个最容易被忽略的环节:撤销权限之后,必须全面验证所有中间件连接池、定时任务脚本、以及 DBA 管理工具(如 OEM、Toad、DBea ver)是否还能正常工作。因为它们很可能隐式依赖了某些刚刚被撤掉的包或视图。
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
同类文章
为什么Oracle触发器中不能直接执行Commit操作_解析自治事务应用
ORA-04092错误:触发器中直接COMMIT会报此错,因Oracle禁止在触发器内提交事务,自治事务需显式声明PRAGMA AUTONOMOUS_TRANSACTION并手动COMMIT,否则自动回滚。 Oracle触发器里执行COMMIT会报什么错 如果你在触发器里直接写上 COMMIT 或
怎样实现PHP中高安全的SQL防注入方案_结合PDO驱动与参数绑定
PDO预处理不能防住所有SQL注入,因默认模拟预处理会拼接参数,且参数绑定仅适用于值,不适用于表名、列名、ORDER BY等结构化部分,须白名单校验。 为什么PDO预处理不能直接防住所有SQL注入 不少开发者有个常见的误解,以为只要代码里用上了 PDO::prepare(),SQL注入的风险就彻底解
SQL中如何进行跨行计算_使用LEAD函数分析趋势
SQL窗口函数LEAD:如何优雅地“向前看”做跨行计算 说到数据分析,尤其是趋势洞察,我们常常需要跳出当前行的局限,看看“后面”发生了什么。这时候,LEAD函数就该登场了。它本质上是一个窗口函数,专门用来获取当前行之后第N行的值。它的基本语法是LEAD(column, offset, default
SQL如何统计每个分组中值的范围区间_使用MIN与MAX函数
SQL分组统计:如何精准获取每个类别的数值范围? 在数据分析工作中,一个高频需求是:按某个维度分组后,快速找出每组数据的最大值和最小值,也就是数值的范围区间。这听起来简单,但实际操作时,稍不注意就会踩到数据质量、语法兼容或性能优化的“坑”。今天,我们就来聊聊这个既基础又关键的技术点。 用 MIN()
SQL如何判断字段是否存在值?IFNULL在数据展示中用法
SQL如何判断字段是否存在值?IFNULL在数据展示中用法 SQL里怎么判断字段有没有值?别只盯着NULL 在数据库里,一个字段“没值”可不仅仅是NULL那么简单。它完全有可能是空字符串 、数字0,甚至是布尔值FALSE。到底算不算“无值”,最终还得看业务逻辑怎么定义。 举个例子就明白了:用户昵称
- 日榜
- 周榜
- 月榜
1
2
3
4
5
6
7
8
9
10
相关攻略
2015-03-10 11:25
2015-03-10 11:05
2021-08-04 13:30
2015-03-10 11:22
2015-03-10 12:39
2022-05-16 18:57
2025-05-23 13:43
2025-05-23 14:01
热门教程
- 游戏攻略
- 安卓教程
- 苹果教程
- 电脑教程
热门话题

