PostgreSQL 临时模式提权漏洞 CVE-2026-116316 深度复盘:pg_temp 类型解析劫持与安全受限操作边界突破

深度剖析 PostgreSQL 高危漏洞 CVE-2026-116316:pg_temp 临时模式下的类型解析路径劫持如何导致普通对象创建者以受害者身份执行任意 SQL。本文从 search_path 解析机制、安全受限操作边界入手,给出 CVSS 8.8 漏洞原理拆解、受影响版本矩阵与生产环境升级加固实操方案,助你在不停机前提下完成 PostgreSQL 临时模式提权漏洞的应急响应与纵深防御。

导语:PostgreSQL 临时模式提权漏洞 CVE-2026-116316 以 CVSS 8.8 的高危评级撕开了一道常被忽视的权限裂缝——攻击者无需任何超级用户权限,仅凭在 pg_temp 中创建一个同名域类型,就能让后续执行未限定类型名查询的受害者会话替自己执行任意 SQL。这不是一次普通的 SQL 注入,而是对 PostgreSQL 类型解析路径与安全受限操作语义边界的一次精准越权。

🎯 核心技术PostgreSQL 类型解析 / search_path
⚡ 架构难度资深架构级 (Level 3-4)
🚀 核心收益CVSS 8.8 提权面收敛 / 零停机加固
📐 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
  
图 1: PostgreSQL 临时模式提权漏洞从 pg_temp 类型投毒到受害者会话越权执行的完整链路

一、漏洞定性:这不是注入,而是解析路径的信任错位

很多团队第一眼看到「执行任意 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 上受影响的版本范围已明确列出。运维侧应优先通过发行版安全源完成补丁落地,而非手工编译。

apt-get update && apt-get install –only-upgrade postgresql-12BASH
点击展开: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

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注