插件门户安全漏洞 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 及更高版本的任何人。

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

更多信息 #

对于安全相关问题,请发送电子邮件至 security@gradle.com

对于非安全相关问题,请在 Github 上打开一个 issue。

讨论