警惕未净化指标名称或标签的注入风险:CVE-2024-28867漏洞深度解析

本文详细分析了Swift Prometheus库中的一个中危漏洞(CVE-2024-28867)。攻击者可通过注入未净化的指标名称或标签数据,接管指标导出格式、导致无限制的指标存储、内存膨胀甚至服务拒绝。文章涵盖了影响、补丁、修复方案及最佳实践。

未净化的指标名称或标签可用于接管导出的指标 · CVE-2024-28867

影响 在将未净化的字符串值应用于指标名称或标签的代码中,例如:

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参考实现中的方法一致。

讨论 强烈建议不要使用未净化的用户输入作为名称或标签,因为它们即使在此漏洞被修补后,也可能导致指标的无限制增长,从而造成拒绝服务攻击的机会——无论库对输入的净化做得多么好。我们强烈建议仅使用一组经过净化的值作为您的指标名称和标签。例如,“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 让我们注意到这个问题。

参考


漏洞详情

swift (github.com/swift-server/swift-prometheus)

受影响版本 = 2.0.0-alpha.1

已修复版本 2.0.0-alpha.2

严重程度 中等(CVSS 总体评分:5.9)

CVSS v3 基础指标

  • 攻击向量:网络
  • 攻击复杂度:高
  • 所需权限:无
  • 用户交互:无
  • 作用范围:未改变
  • 机密性影响:无
  • 完整性影响:高
  • 可用性影响:无 CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:N

EPSS 评分 0.171% (第39百分位)

弱点

  • CWE-74: 对输出中供下游组件使用的特殊元素进行不当中和(注入)
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计