一、漏洞简介

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 触发条件(如特定模块、特定配置、特定运行环境等)

  1. Prometheus 版本在受影响范围内
  2. 攻击者需要诱导用户点击特制链接
  3. 用户当前已登录或信任该 Prometheus 实例
  4. 注意: 使用 --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.12.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/