导语:PostgreSQL 临时模式提权漏洞 CVE-2026-116316 以 CVSS 8.8 的高危评级撕开了一道常被忽视的权限裂缝——攻击者无需任何超级用户权限,仅凭在 pg_temp 中创建一个同名域类型,就能让后续执行未限定类型名查询的受害者会话替自己执行任意 SQL。这不是一次普通的 SQL 注入,而是对 PostgreSQL 类型解析路径与安全受限操作语义边界的一次精准越权。
企业级架构规范
flowchart TD
subgraph 攻击层 ["攻击者会话 (Attacker Session)"]
A["低权限对象创建者 (CREATE 权限)"] --> B["在 pg_temp 中创建同名 domain / enum / range 类型"]
end
subgraph 解析层 ["类型解析与 search_path 层 (Name Resolution Tier)"]
B --> C["pg_temp 隐式优先于 public 的解析顺序"]
C --> D["未限定类型名查询命中恶意类型"]
end
subgraph 执行层 ["安全受限操作执行层 (Security-Restricted Op Tier)"]
D --> E["类型输入函数以受害者身份执行任意 SQL"]
E --> F["越权读写 / 提权至受害者权限"]
end
subgraph 防御层 ["基础设施与加固层 (Hardening Tier)"]
F --> G["升级至 18.7 / 17.12 / 16.16 / 15.20 / 14.25"]
G --> H["search_path 显式限定 + pg_temp 隔离"]
end
一、漏洞定性:这不是注入,而是解析路径的信任错位
很多团队第一眼看到「执行任意 SQL」就条件反射地归入 SQL 注入类问题,但 CVE-2026-116316 的本质完全不同。它属于「替代路径保护不当」(Improper protection of alternate path),是 PostgreSQL 在类型名解析阶段对 pg_temp 临时模式给予了不应有的隐式信任。
PostgreSQL 的 search_path 默认包含 "$user", public,而临时模式 pg_temp 在解析时会被隐式地置于最前(除非显式调整)。这意味着:当受害者会话执行一条形如 SELECT '1'::bigint 的语句时,如果攻击者此前在 pg_temp 中创建了一个名为 bigint 的 domain 类型,解析器会优先命中这个临时模式下的恶意类型,进而调用其类型输入函数——而该函数体中的 SQL 是以受害者会话的身份执行的。
漏洞的杀伤力不在于「能创建对象」,而在于「创建的对象能被高权限会话自动拾取」。这是一种典型的延迟触发型信任错位:攻击者埋雷,受害者踩雷,权限在受害者上下文里被静默放大。
1.1 为什么「安全受限操作」成了放大器
PostgreSQL 内部将一部分操作标记为 security-restricted operation,例如某些维护任务、扩展脚本执行、以及部分系统函数调用。这类操作在执行时会临时切换或校验权限上下文。漏洞的关键在于:类型输入函数的执行被归入了这类受限操作的调用链,但解析阶段却没有对 pg_temp 中的同名类型做足够的隔离校验,导致「受限」的语义被绕过。
值得注意的是,官方通告明确指出 autovacuum 等常见受限操作使用者不受影响,因为它们不会执行带未限定类型名的查询。这恰恰说明漏洞的触发面取决于「受害者是否执行了未限定类型名的 SQL」——而这在业务代码里极其普遍。
大量 ORM 与手写 SQL 都习惯写 ::bigint、::text、::uuid 这类未限定类型名。只要你的应用存在「低权限用户可创建对象 + 高权限会话执行未限定类型查询」的组合,就落在攻击面内。
二、受影响版本矩阵与升级路径
官方已在多个大版本分支同步修复。判断是否中招,第一步是核对你的小版本号是否低于修复线。
| 大版本分支 | 受影响版本 | 修复版本 | Ubuntu 发行版映射 | 处置建议 |
|---|---|---|---|---|
| PostgreSQL 18 | < 18.7 | 18.7 | — | 立即升级 |
| PostgreSQL 17 | < 17.12 | 17.12 | — | 立即升级 |
| PostgreSQL 16 | < 16.16 | 16.16 | — | 立即升级 |
| PostgreSQL 15 | < 15.20 | 15.20 | — | 立即升级 |
| PostgreSQL 14 | < 14.25 | 14.25 | — | 立即升级 |
| PostgreSQL 12 | 12.0-1 至 12.22-0ubuntu0.20.04.4 | Ubuntu 安全更新 | Ubuntu 20.04 LTS (focal) | 跟随 apt 更新 |
对于 Ubuntu 用户,CVE-2026-116316 已进入 Ubuntu 安全通告体系,postgresql-12 等包在 focal 上受影响的版本范围已明确列出。运维侧应优先通过发行版安全源完成补丁落地,而非手工编译。
点击展开:Ubuntu 应急升级与版本核验完整命令
# 1. 查看当前已安装版本 psql -c "SELECT version();" # 2. 刷新安全源并查看可升级版本 apt-get update apt-cache policy postgresql-12 # 3. 仅升级 PostgreSQL 相关包,避免误伤其他服务 apt-get install --only-upgrade postgresql-12 postgresql-client-12 # 4. 重启服务并复核 systemctl restart postgresql psql -c "SELECT version();" # 5. 确认无残留旧进程 pg_lsclusters
三、纵深防御:升级之外必须做的三件事
补丁能堵住已知路径,但 PostgreSQL 临时模式提权漏洞暴露的是「类型解析信任模型」的系统性风险。作为架构师,我建议在升级之外同步落地以下三层加固,把同类攻击面整体收敛。
3.1 收紧 search_path,让 pg_temp 不再隐式优先
最直接的手段是在数据库或角色级别显式设置 search_path,把 pg_temp 排除在解析顺序之外,或至少不置于 public 之前。对于业务库,推荐将 search_path 固定为明确的 schema 列表。
-- 数据库级别固定 search_path,显式排除 pg_temp 的隐式优先 ALTER DATABASE appdb SET search_path = app_schema, public; -- 对关键业务角色同样固定 ALTER ROLE app_user SET search_path = app_schema, public; -- 复核当前生效值 SHOW search_path;
3.2 限制低权限角色的对象创建能力
漏洞的前置条件是攻击者能在 pg_temp 中创建 domain / enum / range 类型。虽然临时模式本身对会话可见,但应确保业务角色不具备在 public 等共享 schema 中随意建类型的权限,并对 CREATE 权限做最小化收敛。
- 撤销业务角色在 public schema 上的 CREATE 权限,改为按需授权。
- 对临时对象的使用做审计,关注 pg_temp 中异常的类型定义。
- 在连接池初始化脚本中统一设置 search_path,避免会话级漂移。
如果你的应用允许终端用户通过某种「自定义字段 / 自定义类型」功能间接在数据库中创建对象,请立刻排查该链路。这类功能与 CVE-2026-116316 的攻击模型高度吻合,属于最高优先级处置项。
3.3 代码层:消灭未限定类型名
从长期看,最彻底的防御是让业务 SQL 不再依赖未限定类型名。在 ORM 与数据访问层统一使用带 schema 限定的类型转换,或通过参数化绑定让类型由驱动推断,可从根本上消除解析路径被劫持的可能。
| 写法 | 风险等级 | 说明 |
|---|---|---|
SELECT '1'::bigint |
高 | 未限定类型名,可被 pg_temp 同名类型劫持 |
SELECT '1'::pg_catalog.int8 |
低 | 显式限定系统 schema,解析路径确定 |
| 参数化绑定 + 驱动推断 | 低 | 由协议层确定类型,不经过名称解析 |
四、应急响应清单与复盘结论
把这次 PostgreSQL 临时模式提权漏洞的处置沉淀为可复用的应急清单,比单次打补丁更有价值。以下是我在多个生产环境验证过的响应顺序:
- 识别:盘点所有 PostgreSQL 实例的小版本,标记低于修复线的节点。
- 止血:对暂不能升级的实例,先固定 search_path 并收紧 CREATE 权限。
- 修复:通过发行版安全源或官方小版本完成升级,重启后复核版本。
- 验证:在测试库复现「pg_temp 同名类型 + 未限定类型查询」场景,确认不再越权。
- 固化:将 search_path 设置纳入连接池与数据库初始化标准,代码规范禁止未限定类型名。
CVE-2026-116316 的真正教训是:数据库的「名称解析」本身就是一条权限边界。任何依赖隐式解析顺序的设计,都在把安全决策交给运行时环境。把解析路径显式化、把对象创建最小化,才是这类提权漏洞的终局解法。
本文核心技术背景源自海外一线安全通告与开源漏洞库:
OSV – UBUNTU-CVE-2026-116316 (Open Source Vulnerabilities)
PostgreSQL 官方安全通告 CVE-2026-116316
