remote_write 实现的 Prometheus 存储型 XSS针对 CVE-2026-40179(GHSA-vffh-x6r8-xx99)的一个最小化、低依赖的概念验证:通过未认证的 remote_write 接口,在 Prometheus Web UI 中实现存储型跨站脚本攻击。
Prometheus 3.x 在将指标名称和标签值渲染到 Web UI 时使用了 innerHTML 且未进行转义。由于 Prometheus v3 放宽了标签验证规则以允许任意 UTF-8 字符 — 包括 <、> 和 " — 指标名称可以携带 HTML 载荷,当有人浏览 UI 时便会执行。
| 受影响版本 | Prometheus 3.0.0 – 3.5.1 |
| 修复版本 | 3.5.2 |
| 影响 | 存储型 XSS,会在任何查看受影响指标的用户浏览器中执行 |
| 受影响界面 | 图表页面工具提示、Metrics Explorer(指标浏览器) |
XSS 本身需要一种方式将构造好的序列写入 TSDB。以下任一方式均可:
remote_write 接口(本 PoC 所使用的方式),暴露在互联网或局域网中、且前方没有身份认证的 Prometheus 会同时提供上述所有条件,这正是该漏洞可实际利用而非仅停留在理论上的原因。
发送单个 POST /api/v1/write 请求,其中包含一个时间序列,其 __name__ 为:
pentest_poc_cve_2026_40179
protobuf WriteRequest 由手写代码以约 40 行完成编码,因此不依赖 protobuf、prometheus_pb2 或 promtool — 仅需 python-snappy 进行线路压缩,以及 requests 发送 POST 请求。这样便可轻松部署到无法构建生成式 protobuf 存根的跳板机上。
python3 -m pip install python-snappy requests
python-snappy 需要 Snappy C 库:
# Debian/Ubuntu
sudo apt install libsnappy-dev
# macOS
brew install snappy
python3 cve-2026-40179-poc.py <target_ip>
此脚本假定目标为 9090 端口上的 HTTPS,并已禁用证书验证(典型情况是使用自签名证书的内部实例)。如果目标是纯 HTTP 或使用其他端口,请修改 main() 中的 url 行。
注入成功会返回 HTTP 204:
POST https://192.0.2.10:9090/api/v1/write -> 204
在 Prometheus UI 或 API 中查询该序列 — 应该会立即返回结果:
{__name__=~"pentest_poc.*"}
Table 视图会正确转义该载荷并将其显示为纯文本。这是预期行为,并非漏洞所在界面。
打开 Metrics Explorer(查询框旁边的指标浏览器),搜索 pentest_poc,然后将鼠标悬停在列出的条目上。
在针对 3.2.1 的实地测试中,Metrics Explorer 路径稳定触发,而 Graph 选项卡的工具提示未能复现 — 注入的样本(值 1.0)未在绘制的图表上可见渲染,悬停图例也未触发。公告中列出了这两个界面;如果在目标版本上其中一个未触发,在断定其不存在漏洞之前,请先尝试另一个。
默认载荷使用 console.log(),因此不会干扰未在寻找它的人。如需可见的演示 — 例如为报告截图 — 可将 METRIC_NAME 改为使用 alert():
METRIC_NAME = ('pentest_poc_cve_2026_40179'
'')
注入的序列是持久化的。 一旦写入,便会一直保留在 TSDB 中,直到保留策略将其过期清理。要删除它需要用到 admin API,而该 API 默认处于禁用状态:
# Only works if Prometheus was started with --web.enable-admin-api
curl -X POST -g 'https://<target>:9090/api/v1/admin/tsdb/delete_series?match[]={__name__=~"pentest_poc.*"}'
curl -X POST 'https://<target>:9090/api/v1/admin/tsdb/clean_tombstones'
如果 admin API 已关闭,则不存在远程清理途径。唯一的替代方案是在主机上本地运行 promtool tsdb,而您很可能没有该权限。
实际后果:
job="pentest_poc"),因此易于查找且明显是测试产物。若要在一次性实例而非任何在线环境中复现:
docker run --rm -p 9090:9090 prom/prometheus:v3.2.1 \
--config.file=/etc/prometheus/prometheus.yml \
--web.enable-remote-write-receiver \
--web.enable-admin-api
然后将脚本指向 127.0.0.1(在 main() 中将 URL 协议改为 http://)。使用 --web.enable-admin-api 启动意味着之后可以实际删除该序列。
--web.config.file 配置 basic_auth_users。--web.enable-remote-write-receiver,并且绝不要以未认证方式将其暴露。请注意,仅执行 (1) 即可修复 XSS,但未认证的 Prometheus 本身仍然是严重的信息泄露面:完整的指标名称列表、抓取目标清单以及内部主机名均可无需凭据即可读取。
此工具面向在授权下工作的防御者、研究人员和测试人员发布。该漏洞已公开披露,并已在上游修复。
对系统运行此工具会向其写入持久化数据。请勿将其指向您不拥有、或未获得明确书面许可进行测试的基础设施。
MIT — 参见 LICENSE。