Swift-Prometheus库曝出注入漏洞:攻击者可劫持监控指标

本文详细分析了CVE-2024-28867漏洞,该漏洞存在于swift-server/swift-prometheus库中。攻击者可通过注入未净化的指标名称或标签来劫持导出的监控指标格式,导致内存无限增长或伪造指标,进而可能引发拒绝服务攻击。

漏洞详情

包名: swift (github.com/swift-server/swift-prometheus) (Swift) 受影响版本: = 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字符。开发人员必须自行验证标签,不允许恶意输入。

此处采取的方法借鉴了Go参考实现的思路。

讨论

强烈建议不要使用未净化的用户输入作为名称或标签,因为即使此漏洞已修复,它们仍可能导致指标无限增长,从而造成拒绝服务(DoS)攻击机会——无论库的输入净化做得有多好。我们强烈建议仅使用一组经过净化的值作为指标名称和标签。例如,“lang”标签应仅使用一组预期的可用值,并忽略其他值——否则,有决心的攻击者可以为每个不同的标签键创建一个指标,导致内存使用量无限增长,因为具有不同值的指标必须保存在内存中。

验证标签值: 该库不会自动验证和替换作为标签值提供的字符串。 开发人员必须自行验证标签值,强烈建议只接受一组已知的值。

可以配置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)

临时解决方案

开发人员在使用用户输入作为指标名称、标签名称或值之前,必须对其进行验证。这遵循了不信任任何未经验证的用户输入的通用安全实践。

致谢

我们要感谢Jonas Dörr提请注意此问题。

参考资料

严重性

中等 CVSS 总体评分: 5.9 / 10 CVSS v3 基础指标: AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:N

弱点

CWE-74: 对输出给下游组件使用的特殊元素进行不当中和(注入) 产品使用来自上游组件的外部影响输入来构建全部或部分命令、数据结构或记录,但在将其发送到下游组件时,没有或错误地中和了可能修改其解析或解释方式的特殊元素。

CVE ID: CVE-2024-28867 GHSA ID: GHSA-x768-cvr2-345r

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