PostgreSQL CVE-2026-6471(PostGREShell):拿到 REPLICATION 账号就能在数据库进程里执行代码
2026 年 9 月 4 日,安全研究机构 Cyera 披露了 PostgreSQL 9.4 至 18 系列中的一个漏洞 CVE-2026-6471,命名为 PostGREShell,CVSS 评分 7.2。根因是逻辑解码(Logical Decoding)的授权缺陷:持有 REPLICATION 属性的低权限账号,可以给逻辑复制槽指定恶意输出插件,插件加载环节突破原本的文件访问限制,最终以运行 PostgreSQL 服务的操作系统账号权限执行任意代码。
复制账号通常被备份工具、备库、CDC 数据同步管道和监控系统使用,没有 DBA 权限,却因此成为突破数据库边界的跳板。
漏洞点在插件加载:从复制权限到 dlopen()
正常情况下,非超级用户只能加载管理员指定目录中的输出插件。CVE-2026-6471 的问题在于,PostgreSQL 对逻辑解码输出插件名称缺乏充分的路径限制和校验:具备 REPLICATION 属性的账号可以把完整文件系统路径(包含目录遍历路径)交给插件加载器,PostgreSQL 最终用 dlopen() 加载攻击者指定的共享库。
被加载的代码直接运行在 PostgreSQL 进程地址空间内,没有额外沙箱隔离。攻击者由此从「复制权限」扩展到操作系统层面的代码执行能力,并进一步提权为 PostgreSQL 超级用户,修改权限相关系统目录,建立可以持续存在的后门。
影响范围与利用前提
这条代码路径从 2014 年 PostgreSQL 9.4 引入逻辑解码时就存在,理论上影响 9.4 至 18 的多个版本;研究人员在 PostgreSQL 18.2 环境中做了验证。
并非所有安装 PostgreSQL 的系统都天然可利用,需要同时满足两个条件:
- 攻击者先拿到具有 REPLICATION 属性的账号;
- 服务器启用了逻辑复制所需配置,例如
wal_level=logical。
现实环境中,备份、容灾、数据同步、CDC 和监控系统经常持有这类权限,所以这个原本被认为「只用于复制数据」的账号,实际是高价值攻击凭证。
权限链与持久化
漏洞体现的是链式突破:
低权限账号 → REPLICATION 权限 → 任意代码加载 → PostgreSQL 进程代码执行 → 数据库超级用户 → 操作系统层面进一步控制。
完成超级用户提升后,攻击者可以访问数据库中全部数据,读取数据库服务账号能够访问的文件、密钥和配置文件,也可以把数据库服务器当作横向移动的跳板。研究人员还指出,攻击者可以建立持久化机制,简单地删除或恢复超级用户权限并不足以保证系统已经清理干净。出现账号被盗迹象时,只做「改密码、删账号」不够,需要开展完整的数据库与服务器入侵排查。
修复版本与 output_plugin_libraries
官方已经通过安全版本修复:
- 18.6
- 17.11
- 16.15
- 15.19
- 14.24
修复增加了 output_plugin_libraries 服务器参数,用于明确限制可以作为逻辑解码输出插件加载的库,默认允许 pgoutput 和 test_decoding。升级到对应安全版本之外,还需要梳理所有具有 REPLICATION 属性的账号,确认业务必要性,删除不再使用或权限过大的复制账号,重点检查备份系统、CDC 平台、数据同步工具和监控系统使用的数据库凭证。
处置清单:升级 → 查账号 → 缩权 → 排查痕迹
下面的 SQL 和命令是常见做法,执行前请按自身版本与环境核对。
1. 升级并确认版本
升级到上述安全版本并重启,然后核对:
SELECT version();
2. 确认逻辑解码配置
SHOW wal_level;
如果备份或 CDC 依赖逻辑复制,不能直接关掉,应通过 output_plugin_libraries 收紧可加载的插件库,只保留业务实际需要的项。
3. 梳理 REPLICATION 账号
SELECT rolname, rolsuper, rolcanlogin, rolvaliduntil
FROM pg_roles
WHERE rolreplication;
注意角色继承,确认没有账号通过成员关系间接获得 REPLICATION:
SELECT r.rolname AS member, g.rolname AS granted_role
FROM pg_auth_members m
JOIN pg_roles r ON r.oid = m.member
JOIN pg_roles g ON g.oid = m.roleid
WHERE g.rolreplication;
再看当前连接与复制槽:
SELECT pid, usename, application_name, client_addr, backend_start
FROM pg_stat_activity
WHERE usename IN (SELECT rolname FROM pg_roles WHERE rolreplication);
SELECT slot_name, plugin, slot_type, database, active, restart_lsn
FROM pg_replication_slots;
pg_replication_slots.plugin 出现 pgoutput、test_decoding 之外的取值时,需要直接查清来源。
4. 按业务必要性缩小权限
不再承担复制任务的账号执行:
ALTER ROLE NOREPLICATION;
备份、CDC、监控各自使用独立账号,密码轮换,只保留各自需要的最小权限,同时检查这些系统里数据库凭证的存放位置和读取范围。
5. 排查入侵痕迹
重点看这几类信号:非预期的输出插件名称、Postgres 服务账号权限范围内新增或修改的共享库文件、日志中的插件加载错误、pg_authid / pg_auth_members 等系统目录的非预期变更,以及 pg_replication_slots 中来源不明的槽。
数据库安全不能只盯 DBA 账号和超级用户。备份、复制、同步、监控这类技术账号同样是边界入口。需要覆盖的链条是:账号权限 — 数据库功能 — 插件加载 — 操作系统权限 — 持久化行为。