pgAdmin 4 新增 LLM 面板,附带一组经典的 LFI+SSRF(CVE-2026-7817)
pgAdmin 4 9.15 修复了新 LLM API 配置端点中的认证型 LFI 和 SSRF。漏洞类别已有四十年历史,攻击面却是全新的。
这是什么?
2026 年 5 月 11 日,pgAdmin 项目披露了 CVE-2026-7817:pgAdmin 4 9.13 和 9.14 中随附的 LLM API 配置端点存在两个相关漏洞。报告者 j3seer 发现两个用户可设置的偏好项 — api_key_file 与 api_url — 未经任何校验便流入 LLM 提供商客户端。已认证的 pgAdmin 用户可借此读取服务器进程可访问的任意文件(本地文件包含,LFI),并强制服务器向内部目标发起 HTTP 请求,例如云元数据服务(服务器端请求伪造,SSRF)。修复在 pgAdmin 4 9.15 中通过提交 24485fe96 发布。
漏洞类别本身已有四十年历史,新鲜的是攻击面:pgAdmin 的 LLM 面板 — 一款辅助编写 SQL 查询的助手 — 成为通往网络与文件系统的桥梁。随着 2026 年越来越多的传统产品加入”向助手提问”面板,完全相同形态的漏洞将不断出现。
漏洞原理
LLM 面板允许用户通过配置两个值将 pgAdmin 指向兼容 OpenAI 的端点:一个是 API 基础 URL,另一个是包含密钥的文件路径。两者都被存为用户偏好,由 chat 路径和模型列表端点消费。
简化自 GitHub issue 与 9.15 补丁的脆弱形态:
# 易受攻击 (< 9.15) — LLM 客户端构造的伪代码
api_url = preferences.get("llm.api_url") # 任意字符串
api_key_path = preferences.get("llm.api_key_file") # 任意路径
with open(api_key_path, "r") as f: # LFI:任何 pgAdmin 可读的文件
api_key = f.read()
client = OpenAIClient(base_url=api_url, # SSRF:任何 URL,包括
api_key=api_key) # http://169.254.169.254/...
由此衍生两种可达行为:
- 通过
api_key_file的 LFI。 路径由 pgAdmin 服务账户打开,内容随后被作为 API 密钥递交给提供商客户端。最自然的观测方式是错误路径 — 一个格式错误的密钥会触发响应,确认读取确实发生,某些配置下甚至回显其片段。将该字段指向服务账户配置、私钥或凭据文件,即可确认外泄。 - 通过
api_url的 SSRF。 该字符串原样用作出站 HTTP 的基础 URL。在云上托管的 pgAdmin 中将其设为http://169.254.169.254/latest/meta-data/iam/security-credentials/,即可代表攻击者拉取实例元数据凭据。chat 与模型列表端点均会进入此代码路径。
利用前提是已认证,这是 CVSS 维持在 6.5(CVSS 3.1)/ 7.1(CVSS 4.0)的唯一原因。在开放自助注册、SSO 映射宽松或低权账户外泄的 pgAdmin 实例上,这一前提很容易达成。
9.15 的补丁简短,值得一读。它在 LLM 偏好的边界做了三件事:把 api_key_file 限制在用户的私有存储(server 模式)或主目录(desktop 模式),要求文件为可打印 ASCII 且读入不超过 1024 字节,并在每个入口点用新增的允许列表(config.ALLOWED_LLM_API_URLS)对 api_url 进行白名单校验。
为什么重要
按 2026 年出现频率排列的三点。
第一,外挂的 LLM 面板成为旧漏洞的新攻击面。pgAdmin 推出一个小型 AI 功能,就在接缝处继承了 CWE-552(LFI)和 CWE-918(SSRF)。同样的模式正在数据库工具、IDE、工单系统、可观测性面板中重演 — 每个都在添加”在此配置你的 LLM 提供商”。任何未经校验便抵达 open() 或 HTTP 客户端的偏好字段都是候选。
第二,认证不等于安全。修改 LLM 偏好所需的 pgAdmin 角色,任何能登录并编辑自身设置的用户都拥有。对于 SSO 后的多租户 pgAdmin — 在金融科技与平台工程中很常见 — 现实中的攻击者就是任何具备企业身份、并有理由把工具对准自己 pgAdmin 标签页的人。
第三,针对云元数据的 SSRF 仍是托管 PostgreSQL 集群中收益最高的认证后跳板。如果 pgAdmin 运行在挂载了实例角色的 EC2、GCE 或 AKS 上,SSRF 即可读取该角色的 STS 凭据。这些凭据继而读取数据库密钥、RDS 快照桶以及该角色被授予访问的一切。CVE-2026-7817 的价值,不在漏洞本身,而在它所处的环境。
这一模式 2026 年早些时候已在 LMDeploy CVE-2026-33626(推理服务器中的 SSRF)与 LiteLLM CVE-2026-42208(LLM 代理中的 SQLi)中出现过:三年前并不存在的软件中出现的经典 Web 漏洞,而这些软件紧邻凭据与模型流量。
防御措施
- 升级到 pgAdmin 4 9.15 或更高版本。 补丁见 9.15 release notes,与同 release 中的其他七个安全修复(CVE-2026-7813 至 CVE-2026-7820)一同打包。不要单独挑选本项。
- 升级前审计现有 LLM 偏好。 从 pgAdmin 数据库导出 preferences 表,排查指向用户存储区之外的
api_key_file,以及不是https://api.openai.com、https://api.anthropic.com或你确实在使用的提供商的api_url。其余要么是错误配置,要么是被利用的证据。 - 显式设置
config.ALLOWED_LLM_API_URLS。 升到 9.15 后,在config_local.py中以你团队真正使用的两三个提供商端点声明该允许列表。默认值偏保守,但控制的价值来自精确收窄。 - 阻止 pgAdmin 出站访问 RFC1918 与 link-local。 在云上托管的 pgAdmin 上,从 pgAdmin 主机拒绝去往
169.254.0.0/16、127.0.0.0/8与相关 RFC1918 段的出站流量,数据库本身除外。即便未来某变体绕过允许列表,这一规则也能中和 SSRF 的影响。在 AWS 上,优先采用 IMDSv2 并将 hop limit 设为 1,使服务器侧请求根本无法触达元数据服务。 - 以专用低权账户运行 pgAdmin。 LFI 向量只能读取 pgAdmin 进程能读取的内容。一个 home 目录为空、组成员不含
ssl-cert、shadow或 cloud-init 凭据路径的服务账户,将让该读原语失去大半价值。 - 将此教训推广到你自己的 LLM 面板。 若产品中有”添加你的 LLM 提供商”页面,请把 API URL 当作任何其他用户控制的、要喂给 HTTP 客户端的 URL 来处理(白名单 scheme、host、port;一次解析,固定后续使用),把密钥路径当作任何其他用户控制的文件路径来处理(限定到用户可写目录、限制读取长度、拒绝符号链接)。pgAdmin 9.15 的补丁是一个可借鉴的参考形态。
状态
| 项目 | 出处 | 日期 | 备注 |
|---|---|---|---|
| Issue 提交 | pgAdmin GitHub #9900 | 2026-05-01 | 由 j3seer 报告 |
| CVE 分配 | CVE-2026-7817 | 2026-05-11 | NVD 发布 |
| pgAdmin 4 9.15 发布 | pgAdmin 项目 | 2026-05-11 | 共八个安全修复 |
| 补丁提交 | 24485fe96 | 2026-05-11 | 允许列表 + 路径限定 + ASCII 校验 |
| 第三方分析 | SentinelOne | 2026-05-18 | 含检测指引 |
| 严重性 | NVD | — | CVSS 3.1:6.5 / CVSS 4.0:7.1 |
| 受影响版本 | pgAdmin 项目 | — | 9.13 ≤ version < 9.15 |
正确的结论不是”pgAdmin 出了一个 bug”。而是 “LLM 配置边界正在成为成熟产品中常规出现 LFI 与 SSRF 的位置,而用来守住它的校验范式已经成型”。先打补丁;再把范式应用到你自己的产品上。
Sources
- → https://github.com/pgadmin-org/pgadmin4/issues/9900
- → https://www.cve.org/CVERecord?id=CVE-2026-7817
- → https://www.pgadmin.org/docs/pgadmin4/9.15/release_notes_9_15.html
- → https://www.postgresql.org/about/news/pgadmin-4-v915-released-3295/
- → https://www.sentinelone.com/vulnerability-database/cve-2026-7817/