Plugin Portal Security CVE-2020-7599

Important update when publishing plugins to the Plugin Portal

A security vulnerability was reported to us on March 4th, 2020. This problem could allow an authorized person to overwrite plugin artifacts on the Plugin Portal if they had access to the build logs that published the plugin. After a thorough investigation, we found no artifacts were overwritten for a malicious purpose.

In response, we’ve published a new version of the com.gradle.plugin-publish plugin that contains an update to mitigate this security vulnerability.

Please upgrade com.gradle.plugin-publish plugin to version 0.11.0. Old versions of the com.gradle.plugin-publish plugin will no longer work. If you do not publish plugins to the Plugin Portal, you do not need to do anything.

We also recommend that builds handling sensitive information (like publishing builds) do not run with elevated log levels (like --debug with Gradle) and are kept private to minimize the damage that can be done if sensitive information is exposed. You should also follow the best practices of your CI provider to avoid leaking sensitive information into build logs (as an example, Travis CI). Like other software, build maintainers and plugin authors need to keep in mind the types of information that may be logged.

This post is a summary of what we found and how we verified that artifacts served by the Plugin Portal were not changed. Continue reading if you’re interested in what we uncovered.

Discovery of the Vulnerability

On March 4th, 2020, we were notified about a security vulnerability with uploads to the Plugin Portal. The vulnerability could allow anyone with access to the log file from the build that published the plugins to overwrite the plugin’s artifacts when info level logging is enabled. This is an information disclosure vulnerability (CWE-532: Insertion of Sensitive Information into Log File) for the Plugin Publish Plugin and is tracked by CVE-2020-7599.

Thanks to Danny Thomas from Netflix for reporting this issue to us.

When a plugin is published to the Plugin Portal, a pre-signed AWS S3 URL is passed to the com.gradle.plugin-publish plugin to upload artifacts. This URL was valid for 1 hour and could be re-used. By default, this URL was never shown to the user, but if the build ran with an elevated log level (--info or --debug), the pre-signed URL was captured in the build log file. With this URL, an attacker could then overwrite the plugin’s artifacts within that 1 hour window.

In general, it’s important that publicly facing builds be cautious with what is logged to their build output. Most CI systems attempt to filter out sensitive data from build logs, but in some cases, they may not hide everything; none of the CI providers filter these kinds of URLs as far as we know. Running your build with debug level logging can expose sensitive information about your infrastructure, passwords or internal web endpoints. This vulnerability was made possible with builds that ran with info level logging enabled.

Remediation and Investigation

After our investigation, we found no maliciously overwritten artifacts.

Once we became aware of the vulnerability, we deployed a change to limit the lifespan of the pre-signed URL. This greatly shortened the window of attack. Due to the way the com.gradle.plugin-publish plugin works, the URL needs to remain valid for some amount of time to allow for all of the artifacts to be published.

We also investigated if any artifacts had been compromised. When publishing an artifact to the Plugin Portal, the client reports the SHA256 checksum of the artifact they intend to upload. We record that checksum, which allowed us to compare the original checksum against the checksum of each artifact in the S3 bucket. If the checksum of the artifact in the S3 bucket did not match the original checksum, this may indicate that the artifact was overwritten.

We audited all of the artifacts (over 190,000) available in the Plugin Portal for mismatched artifact hashes. We performed this comparison by downloading the contents of the S3 bucket and comparing the actual SHA256 checksums against our database. We initially identified over 9000 mismatches, but the vast majority of these artifacts were not accessible to users via the Plugin Portal. These artifacts were created for plugins that were deleted or that failed to publish all of their artifacts completely. Only 12 artifacts failed the checksum match and were served from the Plugin Portal. We investigated each of these to determine if they were compromised.

The artifacts consisted of

  • non-executable artifacts, like source, javadoc and groovydoc that did not contain class files (4)
  • artifacts that were mismatched due to an earlier, unrelated, security investigation (2)
  • artifacts that were produced by a non-public build (2)
  • an artifact that was intentionally changed while investigating this vulnerability
  • a jar file that contained only timestamp differences when built locally
  • a pom file with no suspicious content
  • an invalid jar file

None of the artifacts appear to be different in a meaningful way or could have been compromised for a malicious purpose.

We also reached out to several major cloud CI providers to help identify projects that may have been exposing the pre-signed URL in their build logs. We would like to thank the GitHub and CircleCI IR Teams for both being very proactive with their assistance.

Has the problem been patched? What version should I upgrade to?

We have published a new version of the com.gradle.plugin-publish plugin that reduces the log level for the pre-signed URL. Please upgrade com.gradle.plugin-publish to version 0.11.0. Previous versions of this plugin no longer work and will be rejected by the Plugin Portal.

These changes mitigate the exposure of the sensitive URL, but it’s still important that publicly facing builds be cautious with what is logged to their build output. Running Gradle with --debug will still expose the pre-signed URL. Internal JDK logging will log all HTTP requests–not just the artifact URLs.

Going forward, we will be making updates to the Plugin Portal to detect overwritten artifacts and to increase the security around the Gradle plugin ecosystem.

I can’t upgrade. Is there anything I can do?

We’re requiring that everyone update to the latest version of the com.gradle.plugin-publish plugin. This version should work for anyone using Gradle 3.0 and above.

If you run into problems upgrading, please let us know with an issue.

For more information

For security related issues, please email us at security@gradle.com.

For non-security related issues, please open an issue on Github.