插件门户安全 CVE-2020-7599

在插件门户发布插件时的重要更新

我们于 2020 年 3 月 4 日收到关于安全漏洞的报告。此问题可能允许授权人员在访问发布插件的构建日志的情况下,覆盖插件门户上的插件工件。经过彻底调查,我们发现没有工件被恶意覆盖。

作为回应,我们发布了 com.gradle.plugin-publish 插件的新版本,其中包含缓解此安全漏洞的更新。

请将 com.gradle.plugin-publish 插件 升级到版本 0.11.0。旧版本的 com.gradle.plugin-publish 插件将 **不再工作**。如果您没有将插件发布到 插件门户,则无需执行任何操作。

我们还建议处理敏感信息(如发布构建)的构建不要以高级别日志运行(如 Gradle 的 --debug),并保持私密,以最大程度地减少敏感信息泄露时可能造成的损害。您还应遵循 CI 提供商的最佳实践,以避免将敏感信息泄露到构建日志中(例如,Travis CI)。与其他软件一样,构建维护人员和插件作者需要牢记可能记录的信息类型。

这篇文章总结了我们发现的内容以及我们如何验证插件门户提供的工件没有被更改。如果您有兴趣了解我们发现的内容,请继续阅读。

漏洞发现

2020 年 3 月 4 日,我们收到关于插件门户上传的安全性漏洞的通知。该漏洞可能允许任何拥有发布插件的构建日志文件访问权限的人在启用 info 级日志记录时覆盖插件的工件。这是一个针对插件发布插件的信息泄露漏洞(CWE-532:将敏感信息插入日志文件),并由 CVE-2020-7599 跟踪。

感谢来自 Netflix 的 Danny Thomas 向我们报告了此问题。

当插件发布到插件门户网站时,一个 预签名 AWS S3 URL 会传递给 com.gradle.plugin-publish 插件以上传工件。此 URL 有效期为 1 小时,可以重复使用。默认情况下,此 URL 不会显示给用户,但如果构建以更高的日志级别 (--info--debug) 运行,则预签名 URL 会被捕获到构建日志文件中。使用此 URL,攻击者可以在 1 小时内覆盖插件的工件。

通常,面向公众的构建在记录到其构建输出时应谨慎。大多数 CI 系统会尝试从构建日志中过滤掉敏感数据,但在某些情况下,它们可能无法隐藏所有内容;据我们所知,没有 CI 提供商会过滤此类 URL。使用 debug 级别日志运行构建可能会泄露有关您的基础设施、密码或内部 Web 端点的敏感信息。此漏洞是由于启用了 info 级别日志的构建而造成的。

补救和调查

经过调查,我们没有发现任何恶意覆盖的工件。

在我们意识到漏洞后,我们部署了更改以限制预签名 URL 的生命周期。这大大缩短了攻击窗口。由于 com.gradle.plugin-publish 插件的工作方式,URL 需要保持有效一段时间才能允许所有工件发布。

我们还调查了是否有任何工件遭到破坏。在将工件发布到插件门户网站时,客户端会报告他们打算上传的工件的 SHA256 校验和。我们记录了该校验和,这使我们能够将原始校验和与 S3 存储桶中每个工件的校验和进行比较。如果 S3 存储桶中工件的校验和与原始校验和不匹配,则可能表明工件已被覆盖。

我们审核了插件门户网站中所有可用的工件(超过 190,000 个),以查找不匹配的工件哈希值。我们通过下载 S3 存储桶的内容并将实际的 SHA256 校验和与我们的数据库进行比较来执行此比较。我们最初识别出超过 9000 个不匹配,但绝大多数这些工件无法通过插件门户网站访问用户。这些工件是为已删除或未完全发布所有工件的插件创建的。只有 12 个工件未能通过校验和匹配,并且是从插件门户网站提供的。我们调查了每一个工件,以确定它们是否遭到破坏。

这些工件包括

  • 不可执行的工件,例如不包含类文件的源代码、Javadoc 和 Groovydoc(4 个)
  • 由于之前无关的安全调查导致不匹配的工件(2 个)
  • 非公开构建生成的工件(2 个)
  • 在调查此漏洞时有意更改的工件
  • 仅包含本地构建时时间戳差异的 jar 文件
  • 没有可疑内容的 pom 文件
  • 无效的 jar 文件

所有工件似乎都没有以有意义的方式发生变化,或者可能被恶意利用。

我们还联系了几家主要的云 CI 提供商,以帮助识别可能在其构建日志中公开预签名 URL 的项目。我们要感谢 GitHub 和 CircleCI 的 IR 团队,他们积极协助我们。

问题是否已修复?我应该升级到哪个版本?

我们发布了 com.gradle.plugin-publish 插件的新版本,该版本降低了预签名 URL 的日志级别。请将 com.gradle.plugin-publish 升级到版本 0.11.0。此插件的先前版本 **不再有效**,插件门户将拒绝它们。

这些更改减轻了敏感 URL 的暴露,但面向公众的构建仍然需要注意其构建输出中记录的内容。使用 --debug 运行 Gradle 仍然会公开预签名 URL。内部 JDK 日志将记录所有 HTTP 请求,而不仅仅是工件 URL。

今后,我们将对插件门户进行更新,以检测覆盖的工件并提高 Gradle 插件生态系统的安全性。

我无法升级。我该怎么办?

我们要求每个人都更新到最新版本的 com.gradle.plugin-publish 插件。此版本适用于所有使用 Gradle 3.0 及更高版本的用户。

如果您在升级过程中遇到问题,请通过 问题告知我们。

更多信息

有关安全相关问题,请发送电子邮件至 [email protected]

有关非安全相关问题,请在 Github 上创建问题。

讨论