AUTHID CURRENT_USER易引发注入风险,因其使PL/SQL以调用者权限运行,若配合未经校验的动态SQL(如EXECUTE IMMEDIATE拼接用户输入)及高危系统包(如DBMS_EXPORT_EXTENSION),可导致提权。

为什么 AUTHID CURRENT_USER 容易引发注入风险AUTHID CURRENT_USER 让 PL/SQL 单元以调用者权限运行,而不是定义者(如 SYS 或 DBA)权限。这本身是安全设计,但一旦函数/过程体内拼接用户输入进 EXECUTE IMMEDIATE,调用者就能把任意 SQL 注入进去——尤其当该用户已被授予 CREATE PROCEDURE 或能调用含动态 SQL 的系统包(如 DBMS_CDC_SUBSCRIBE、DBMS_EXPORT_EXTENSION)时,风险直接升级为提权。
常见错误现象:
- 用户仅拥有
CONNECT和RESOURCE权限,却通过调用一个看似无害的存储过程获得了DBA - 执行
SELECT * FROM SESSION_PRIVS后突然看到DBA权限 - 日志中出现异常的
ALTER USER SYS IDENTIFIED BY ...或GRANT DBA TO ...操作
如何识别高危动态 SQL 模式
关键看三处是否未经净化就拼接了外部输入:
- EXECUTE IMMEDIATE 字符串中直接拼入变量(如 'ALTER TABLE ' || p_schema || '.' || p_table)
- 存储过程参数未做白名单校验,直接用于对象名、约束名、列名等上下文
- 调用了 Oracle 内置包(如 DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_METADATA、DBMS_CDC_SUBSCRIBE.ACTIVATE_SUBSCRIPTION),而这些包本身接受字符串参数并内部执行动态 SQL
使用场景中需特别警惕:
- 数据迁移脚本里用
p_schema动态切换 schema 执行 DDL - 权限同步工具中根据传入用户名构造
GRANT语句 - 管理界面后台调用
UTL_HTTP.REQUEST或DBMS_SCHEDULER并拼接 URL/program_name
防御建议:
- 所有用于对象名的参数必须通过
DBMS_ASSERT.SIMPLE_SQL_NAME或DBMS_ASSERT.QUALIFIED_SQL_NAME校验 - 避免在
AUTHID CURRENT_USER过程中使用EXECUTE IMMEDIATE;改用静态 SQL + 绑定变量 - 若必须动态执行 DDL,优先走
DBMS_UTILITY.EXEC_DDL_STATEMENT(不支持绑定变量,但仍比裸拼安全)
真实案例中的绕过点:DBMS_EXPORT_EXTENSION
这个包在 Oracle 10g–12c 中长期被用于提权,漏洞根源在于它接受任意字符串作为类型名,并在内部拼接后执行。攻击者可构造如下调用:
SELECT SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_METADATA(
INDEX_NAME => 'A1',
INDEX_SCHEMA => 'CY',
TYPE_NAME => 'HACKERPACKAGE', -- 实际是自定义 package 名
TYPE_SCHEMA => 'CY',
VERSION => '10.2.0.1.0',
GMFLAGS => 1
) FROM DUAL;
其中 HACKERPACKAGE 是攻击者提前创建的 AUTHID CURRENT_USER 包,其 ODCIIndexGetMetadata 函数体含 EXECUTE IMMEDIATE 'GRANT DBA TO ...'。
容易踩的坑:
- 认为“只给 EXECUTE 权限就安全”,但
DBMS_EXPORT_EXTENSION默认是DEFINER权限,调用者借用了SYS上下文 - 忽略
TYPE_NAME参数未校验,导致可传入带双引号的恶意标识符(如"SCOTT"."PWN") - 未禁用或重命名该包(
REVOKE EXECUTE ON SYS.DBMS_EXPORT_EXTENSION FROM PUBLIC是必要操作)
最小权限落地要点
防御不是靠某一个函数,而是权限链上的每环都收紧:
- 禁用所有非必需的高危包:REVOKE EXECUTE ON SYS.DBMS_EXPORT_EXTENSION FROM PUBLIC、REVOKE EXECUTE ON SYS.UTL_HTTP FROM PUBLIC
- 对含 AUTHID CURRENT_USER 的自定义过程,显式限制其能访问的 schema:ALTER SESSION SET CURRENT_SCHEMA = APP_SCHEMA 应在入口处强制执行
- 启用 RESOURCE_LIMIT 并配置 PGA_AGGREGATE_LIMIT,防止恶意动态 SQL 耗尽内存引发实例阻塞
- 审计关键行为:AUDIT EXECUTE ON SYS.DBMS_EXPORT_EXTENSION BY ACCESS,配合 UNIFIED_AUDIT_TRAIL 实时捕获异常调用
真正难防的从来不是单个注入点,而是 AUTHID CURRENT_USER + 动态 SQL + 系统包暴露 + 调用者拥有 CREATE PROCEDURE 这四者叠加——少一环,攻击链就断掉。


















