Swift-Prometheus库安全漏洞解析:未净化指标名称可导致指标导出被劫持

本文详细分析了CVE-2024-28867漏洞,该漏洞存在于swift-server/swift-prometheus库中,攻击者可通过未净化的指标名称或标签劫持导出指标,导致服务器内存使用膨胀和伪造指标等安全问题。

CVE-2024-28867:Swift-Prometheus库安全漏洞分析

漏洞概述

在swift-server/swift-prometheus库中,当代码使用未净化的字符串值作为指标名称或标签时,攻击者可以利用此漏洞接管导出格式。具体攻击方式包括创建无限数量的存储指标、膨胀服务器内存使用量或生成"虚假"指标。

受影响版本

  • 受影响版本:= 2.0.0-alpha.1
  • 已修复版本:2.0.0-alpha.2

漏洞影响

当代码如下所示使用未净化的字符串值时:

1
2
3
4
5
let lang = try? request.query.get(String.self, at: "lang")
Counter(
  label: "language", 
  dimensions: [("lang", lang ?? "unknown")]
)

攻击者可以通过发送包含换行符、}或其他类似字符的?lang查询参数,从而接管导出的指标格式。

修复方案

补丁说明

默认的标签净化策略已更深层次地集成到库中,防止非法字符出现在名称、标签键和值中。

验证要求:

  • 指标名称必须符合:[a-zA-Z_:][a-zA-Z0-9_:]*
  • 指标标签名称必须符合:[a-zA-Z_][a-zA-Z0-9_]*
  • 标签值不进行验证(允许包含任何Unicode字符)

自定义净化配置

开发者可以配置PrometheusSanitizer来应用所需的验证逻辑:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
let mySanitizer = PrometheusSanitizer { metricName, labels in
  // ... 自定义逻辑 ...
  (metricName, labels)
}

let registry = PrometheusCollectorRegistry(sanitizer: mySanitizer)
let factory = PrometheusMetricsFactory(factory: registry)

// swift-metrics
MetricsSystem.bootstrap(factory)

安全建议

  1. 强烈建议不要使用未净化的用户输入作为名称或标签
  2. 仅对指标名称和标签使用经过净化的值集合
  3. 开发者必须在使用用户输入作为指标名称、标签名称或值之前进行验证
  4. 遵循不信任任何未经净化的用户输入的常见实践

技术细节

该修复方法采用了Go参考实现的相同方法。即使此漏洞已修复,使用未净化的用户输入仍可能导致指标的无限制增长,造成拒绝服务攻击机会。

参考信息

  • GHSA ID: GHSA-x768-cvr2-345r
  • CVE ID: CVE-2024-28867
  • 源代码仓库: swift-server/swift-prometheus

致谢

感谢Jonas Dörr报告此问题。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计