一、漏洞简介¶
1.1 漏洞背景¶
2020年12月,Prometheus 2.23.0 版本引入了新的 Web UI 界面。为了确保平滑过渡,开发团队在 /new 端点实现了重定向功能,将旧版 URL 重定向到新版界面。然而,该重定向功能的实现存在缺陷,导致攻击者可以构造恶意 URL 将用户重定向到任意第三方网站。
1.2 漏洞概述(包含 CVE 编号、危害等级、漏洞类型、披露时间等)¶
| 项目 | 内容 |
|---|---|
| 漏洞编号 | CVE-2021-29622 |
| 危害等级 | MEDIUM / 6.5 |
| 漏洞类型 | 开放重定向漏洞 |
| 披露时间 | 2021-05-19 |
| 影响组件 | Prometheus |
- CVE编号: CVE-2021-29622
- 危害等级: 中危
- CVSS评分: 6.1 (CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N)
- 漏洞类型: CWE-601 - URL 重定向到不可信站点(开放重定向)
- 影响组件: Prometheus Web UI
/new端点
补充核验信息:公开时间:2021-05-19;NVD 评分:6.5(MEDIUM);CWE:CWE-601。
二、影响范围¶
2.1 受影响的版本¶
- Prometheus >= 2.23.0 且 < 2.26.1
- Prometheus = 2.27.0
2.2 不受影响的版本¶
- Prometheus < 2.23.0
- Prometheus >= 2.26.1 且 < 2.27.0
- Prometheus >= 2.27.1
- Prometheus >= 2.28.0 (移除了
/new端点)
2.3 触发条件(如特定模块、特定配置、特定运行环境等)¶
- Prometheus 版本在受影响范围内
- 攻击者需要诱导用户点击特制链接
- 用户当前已登录或信任该 Prometheus 实例
- 注意: 使用
--web.external-url参数且配置了路径的用户不受影响
三、漏洞详情与原理解析¶
3.1 漏洞触发机制¶
漏洞存在于 /new 端点的路径处理逻辑中。当 Prometheus 处理 /new/* 路径的请求时,会将 * 部分作为重定向目标,但未对目标 URL 进行充分验证。
问题代码逻辑:
// 简化的问题代码
func handleNewEndpoint(w http.ResponseWriter, r *http.Request) {
// 提取 /new/ 后的路径
path := strings.TrimPrefix(r.URL.Path, "/new/")
// 未验证直接重定向
http.Redirect(w, r, path, http.StatusFound)
}
攻击示例:
正常使用:
http://prometheus:9090/new/graph → 重定向到 http://prometheus:9090/graph
恶意利用:
http://prometheus:9090/new/newhttp://evil.com/phishing → 重定向到 http://evil.com/phishing
3.2 源码层面的根因分析(结合源码与补丁对比)¶
根本原因: 路径验证逻辑存在缺陷,允许绝对 URL 绕过相对路径限制。
补丁分析:
// 修复前
func (h *Handler) newRedirect(w http.ResponseWriter, r *http.Request) {
- path := r.URL.Path[len("/new"):]
- http.Redirect(w, r, path, http.StatusFound)
}
// 修复后
func (h *Handler) newRedirect(w http.ResponseWriter, r *http.Request) {
+ path := r.URL.Path[len("/new"):]
+ // 验证路径必须以 / 开头
+ if !strings.HasPrefix(path, "/") {
+ http.Error(w, "invalid redirect path", http.StatusBadRequest)
+ return
+ }
+ // 确保不会重定向到外部 URL
+ http.Redirect(w, r, path, http.StatusFound)
}
修复措施:
1. 添加路径格式验证
2. 强制要求重定向目标必须以 / 开头
3. 在 2.28.0 版本完全移除 /new 端点
四、漏洞复现(可选)¶
4.1 环境搭建¶
# 使用受影响版本
docker run -d -p 9090:9090 --name prometheus \
prom/prometheus:v2.27.0
4.2 PoC 演示与测试过程¶
测试 1: 验证漏洞存在
访问以下 URL:
http://localhost:9090/new/newhttp://www.google.com/
预期结果: 浏览器会被重定向到 http://www.google.com/
测试 2: 构造钓鱼场景
http://localhost:9090/new/newhttp://evil.com/phishing-page?fake=prometheus
攻击者可以: 1. 伪装成 Prometheus 的合法链接 2. 利用用户对 Prometheus 域名的信任 3. 发起钓鱼攻击或恶意软件分发
测试 3: 组合 XSS 攻击
http://localhost:9090/new/newjavascript:alert('XSS')
注意: 现代浏览器通常会阻止 javascript: 协议的重定向,但这仍是一个安全问题。
五、修复建议与缓解措施¶
5.1 官方版本升级建议¶
推荐升级路径:
- 升级到 Prometheus 2.26.1 或 2.27.1 (包含补丁)
- 升级到 Prometheus 2.28.0+ (完全移除了 /new 端点,彻底解决问题)
# 升级到最新版本
docker pull prom/prometheus:latest
docker stop prometheus && docker rm prometheus
docker run -d -p 9090:9090 --name prometheus prom/prometheus:latest
5.2 临时缓解方案(如修改配置文件、关闭相关模块、增加 WAF 规则等)¶
方案 1: 通过反向代理禁用 /new 端点
Nginx 配置:
server {
listen 80;
server_name prometheus.example.com;
location /new {
# 拒绝访问 /new 端点
return 403 "This endpoint has been disabled for security reasons";
}
location / {
proxy_pass http://localhost:9090;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
方案 2: 使用 web.external-url 参数
# 配置外部 URL 并添加路径前缀
prometheus \
--web.external-url=http://prometheus.example.com/prometheus \
--web.route-prefix=/
这样配置后,URL 格式为 /prometheus/new/*,重定向逻辑会验证完整路径,阻止绕过。
方案 3: Web 应用防火墙规则
Apache ModSecurity:
SecRule REQUEST_URI "@beginsWith /new/new" \
"id:1002,phase:1,deny,status:403,msg:'Open Redirect Attempt Blocked'"
六、参考信息 / 参考链接¶
6.1 官方安全通告¶
- https://github.com/prometheus/prometheus/security/advisories/GHSA-vx57-7f4q-fpc7
- https://github.com/prometheus/prometheus/releases/tag/v2.26.1
- https://github.com/prometheus/prometheus/releases/tag/v2.27.1
6.2 其他技术参考资料¶
- https://nvd.nist.gov/vuln/detail/CVE-2021-29622
- https://cwe.mitre.org/data/definitions/601.html
- https://prometheus.io/docs/introduction/release-cycle/