The Gradle Blog2024-02-13T03:55:34-05:00https://blog.gradle.org/Gradle Wrapper Attack Report2023-01-25T00:00:00-05:00https://blog.gradle.org/wrapper-attack-reportLouis Jacomet
<p>On January 11th 2023, we were contacted by <a href="https://minecraftonline.com/">MinecraftOnline</a> about two unusual and suspicious Gradle wrapper JARs found in some of their repositories.
The wrappers were updated by a new contributor to MinecraftOnline.</p>
<p>We’ve performed an analysis of the JARs and will describe our findings below.
We have determined that one exploit was especially crafted as an attack against the MinecraftOnline project.</p>
<p>If you are not interested in all of the details, jump immediately to our <a href="/project-integrity">companion blog</a> covering how to protect your project or you, as a developer, against similar attacks.</p>
<h2 id="analysis">Analysis</h2>
<p>Our analysis started by confirming that the SHA256 checksums for both JARs did not match any of the <a href="https://gradle.org/release-checksums/">known good Gradle Wrapper checksums</a>:</p>
<ul>
<li>First JAR: <code class="language-plaintext highlighter-rouge">8449b6955690ec956c8ecfe1ae01e10a2aa76ddf18969985c070e345605acce1</code></li>
<li>Second JAR: <code class="language-plaintext highlighter-rouge">8e129181710bdc045423ddde59244586d7acbc0b2c5e2ddfc098559da559cf85</code></li>
</ul>
<p>After decompiling the two JARs, we discovered two exploits had been patched into the wrapper JAR.</p>
<h3 id="discord-credentials-stealing">Discord credentials stealing</h3>
<p>The first exploit, present in both JARs, attempts to steal <a href="https://discord.com">Discord</a> credentials by looking into specific files on the host computer.</p>
<p>The code is very similar to Discord token logging found online.
The exploit hides in different Gradle Wrapper classes and obfuscates <code class="language-plaintext highlighter-rouge">String</code> constants through a character array lookup.</p>
<p>Using a regular expression, lines from certain files are uploaded to a <a href="https://discord.com/developers/docs/resources/webhook#execute-webhook">Discord Webhook</a> using a hardcoded token found in the code.</p>
<h3 id="downloading-and-running-code-locally">Downloading and running code locally</h3>
<p>The second JAR contains an additional exploit.
On certain Gradle invocations, it will attempt to download another malicious JAR and then run it.</p>
<p>For this code path to trigger, the Gradle invocation needed to start with <code class="language-plaintext highlighter-rouge">publish</code> or <code class="language-plaintext highlighter-rouge">magic</code>.
<code class="language-plaintext highlighter-rouge">publish</code> is a Gradle task for pushing all project artifacts to a repository.
Builds that publish artifacts typically have access to higher privileged credentials.
We think that <code class="language-plaintext highlighter-rouge">magic</code> was used as a way to test the exploit.</p>
<p>Running that JAR resulted in the following actions:</p>
<ol>
<li>Edit the <code class="language-plaintext highlighter-rouge">build.gradle</code> file to modify the software being built by adding additional dependencies
<ol>
<li>Add two repositories, first in the list: a file-based one and <code class="language-plaintext highlighter-rouge">mavenCentral()</code></li>
<li>Add dependencies to the <code class="language-plaintext highlighter-rouge">shadow</code> configuration: the downloaded JAR itself and two third party libraries</li>
<li>Relocate the injected code to be in the <code class="language-plaintext highlighter-rouge">org.mariadb.jdbc.internal.cachevalidator</code> package as part of the <a href="https://imperceptiblethoughts.com/shadow/introduction/">Shadow plugin</a> configuration</li>
</ol>
</li>
<li>Modify a project specific source file so that the software would execute the malicious code
<ol>
<li>Add initialization of the code from the injected dependency</li>
</ol>
</li>
</ol>
<p>In addition to the above, the exploit would modify any Gradle invocation that started with <code class="language-plaintext highlighter-rouge">wrapper</code> to invoke <code class="language-plaintext highlighter-rouge">cleanEclipse</code> instead.
We think this was an attempt to make it harder for the malicious wrapper JAR to be removed.</p>
<h3 id="modified-files-in-the-wrapper-jars">Modified files in the wrapper JARs</h3>
<p>For completeness, here are the modified files found in the infected wrapper JARs:</p>
<ul>
<li>First infected wrapper
<ul>
<li><code class="language-plaintext highlighter-rouge">org/gradle/cli/SystemPropertiesCommandLineConverter.class</code>
<ul>
<li>File on <a href="https://www.virustotal.com/gui/file/aebb9a9ed3da2cc639df2fe097bd716d74e3bf68b7a3d890d0a1d62dae27e676/detection">VirusTotal</a></li>
</ul>
</li>
<li><code class="language-plaintext highlighter-rouge">org/gradle/wrapper/Download.class</code>
<ul>
<li>File on <a href="https://www.virustotal.com/gui/file/106e966c3d4f2e799a00b972354ee5df033adcd6e4f5d7fadd07559eefd3be6e?nocache=1">VirusTotal</a></li>
</ul>
</li>
<li><code class="language-plaintext highlighter-rouge">org/gradle/wrapper/PathAssembler.class</code>
<ul>
<li>File on <a href="https://www.virustotal.com/gui/file/b1b717c1e861a37d01763d62a886260d93083df4dfbaecb49cff7a0478ebed87?nocache=1">VirusTotal</a></li>
</ul>
</li>
</ul>
</li>
<li>Second infected wrapper
<ul>
<li><code class="language-plaintext highlighter-rouge">org/gradle/cli/CommandLineParser.class</code>
<ul>
<li>File on <a href="https://www.virustotal.com/gui/file/df17c7f3689b472d77e065f007f3da816e11c408d8a175e731ebcdd2b5871f97/">VirusTotal</a></li>
</ul>
</li>
<li><code class="language-plaintext highlighter-rouge">org/gradle/cli/SystemPropertiesCommandLineConverter.class</code>
<ul>
<li>Same as in the first wrapper</li>
</ul>
</li>
<li><code class="language-plaintext highlighter-rouge">org/gradle/wrapper/Download.class</code>
<ul>
<li>File on <a href="https://www.virustotal.com/gui/file/e63e69972db7fdddf1ab5447d8cc55eb6013e6773210fe94d966e44b7f25829d?nocache=1">VirusTotal</a></li>
</ul>
</li>
<li><code class="language-plaintext highlighter-rouge">org/gradle/wrapper/PathAssembler.class</code>
<ul>
<li>Same as in the first wrapper</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="conclusion">Conclusion</h2>
<p>While the Gradle team is aware of the potential attack vector of injecting a malicious wrapper JAR, this is the first report we received of it being actively exploited as a <a href="https://en.wikipedia.org/wiki/Supply_chain_attack">supply chain attack</a>.</p>
<p>In general, we advise caution when integrating any changes from untrusted sources that may affect your build process. Please report any suspicious projects, wrappers, or distributions to <a href="mailto:security@gradle.com">us</a>.
See the <a href="/project-integrity">companion blog post</a> about how to protect your project or you, as a developer, against similar attacks.</p>
<p>Let us know if you have any questions on our <a href="https://discuss.gradle.org/">forums</a> or <a href="https://gradle.com/slack-invite">Gradle Community Slack</a>, or start a discussion below.</p>
Protecting Project Integrity2023-01-25T00:00:00-05:00https://blog.gradle.org/project-integrityLouis Jacomet
<p>Our recent <a href="/wrapper-attack-report">security report</a> shows that <a href="https://en.wikipedia.org/wiki/Supply_chain_attack">supply chain attacks</a> targeting the build process through the Gradle Wrapper exist in the wild.
This blog post explains how to protect your project or you, as a developer, against similar attacks.</p>
<p>A build process, by design, executes code.
The components of the build process all carry their own risks:</p>
<ol>
<li>The bootstrapping script to run the build tool could be compromised. (see <a href="#how-to-ensure-gradle-wrapper-integrity">How to ensure Gradle wrapper integrity?</a>)</li>
<li>The build tool itself could be compromised. (see <a href="#how-to-ensure-gradle-distribution-integrity">How to ensure Gradle distribution integrity?</a>)</li>
<li>The build tool could download third-party dependencies that are themselves compromised. (see <a href="#how-to-ensure-third-party-dependencies-integrity">How to ensure third party dependencies’ integrity?</a>)</li>
<li>Malicious code could be hidden in the project code, tests or build configuration. (see <a href="#how-to-ensure-project-integrity">How to ensure project integrity?</a>)</li>
</ol>
<p>Because of all those possible attack vectors, you should exercise caution <em>when you are not fully confident in the source of the changes</em>.
In the case of the attack against <a href="https://minecraftonline.com/">MinecraftOnline</a> analyzed in <a href="/wrapper-attack-report">our report</a>, Gradle wrapper updates were done by a new contributor.</p>
<p>Similarly, contributing to open source potentially exposes you to such attacks.
It would be best to validate new projects you are looking into similarly.</p>
<p>The key point is that <strong><em>you should only run a build if you trust the project or change set</em></strong>.</p>
<p>The following recommendations can help establish trust in a local Gradle build.</p>
<h2 id="how-to-ensure-gradle-wrapper-integrity">How to ensure Gradle wrapper integrity?</h2>
<p>Firstly, ensure the integrity of Gradle Wrapper on each change of the wrapper JAR, especially coming from external contributors.
Gradle <a href="https://gradle.org/release-checksums/">publishes the checksums</a> of the <code class="language-plaintext highlighter-rouge">gradle-wrapper.jar</code> for each Gradle version.</p>
<h3 id="wrapper-integrity-for-maintainers">Wrapper integrity for maintainers</h3>
<ul>
<li>Gradle wrapper JARs should always be validated when updated in a repository
<ul>
<li>For those using GitHub actions, Gradle publishes a <a href="https://github.com/marketplace/actions/gradle-wrapper-validation">dedicated action</a> that will validate wrapper checksums</li>
<li>For any other setup, automating that verification can be done by expanding on our <a href="https://docs.gradle.org/current/userguide/gradle_wrapper.html#manually_verifying_the_gradle_wrapper_jar">validation instructions</a></li>
</ul>
</li>
<li>Prefer to update the wrapper yourself instead of merging a PR from an external contributor.
Regenerate the <code class="language-plaintext highlighter-rouge">gradlew</code>, <code class="language-plaintext highlighter-rouge">gradle-wrapper.properties</code>, and <code class="language-plaintext highlighter-rouge">gradle-wrapper.jar</code> from a known good Gradle distribution.
Invoking a local Gradle with <code class="language-plaintext highlighter-rouge">gradle wrapper</code> will not run the <code class="language-plaintext highlighter-rouge">gradle-wrapper.jar</code> of the project <em>but it will configure the build</em>.</li>
</ul>
<h3 id="wrapper-integrity-for-contributors">Wrapper integrity for contributors</h3>
<ul>
<li>If you do not trust the project you are building, prefer using a known good, local Gradle distribution over a wrapper.</li>
</ul>
<h2 id="how-to-ensure-gradle-distribution-integrity">How to ensure Gradle distribution integrity?</h2>
<p>Secondly, ensure the integrity of the Gradle distribution itself.
Alongside the wrapper checksums, you can also find the <a href="https://gradle.org/release-checksums/">distribution checksums</a>.</p>
<h3 id="distribution-integrity-for-maintainers">Distribution integrity for maintainers</h3>
<ul>
<li>Gradle distribution checksum can be <a href="https://docs.gradle.org/current/userguide/gradle_wrapper.html#sec:verification">added to the <code class="language-plaintext highlighter-rouge">gradle-wrapper.properties</code> file</a> to enforce that what is downloaded matches the expected checksum.</li>
</ul>
<h3 id="distribution-integrity-for-contributors">Distribution integrity for contributors</h3>
<ul>
<li>Here again, relying on a known good, local Gradle distribution can be safer.</li>
</ul>
<h2 id="how-to-ensure-third-party-dependencies-integrity">How to ensure third party dependencies’ integrity?</h2>
<p>Ensuring the integrity of third-party dependencies involves evaluating multiple factors, such as the familiarity and reliability of the dependencies or plugins being used, as well as the trustworthiness of the repositories they originate from.
Considering all these factors together is essential to properly verify their integrity.</p>
<h3 id="dependencies-integrity-for-maintainers">Dependencies integrity for maintainers</h3>
<ul>
<li>Gradle allows you to enable <a href="https://docs.gradle.org/current/userguide/dependency_verification.html">dependency verification</a>.
This feature ensures that third party dependencies, both build plugins and project dependencies, match the trusted signature or checksums that are configured.</li>
<li>Be wary of any changes to build scripts that use unusual repositories, plugins, or dependencies.</li>
</ul>
<h3 id="dependencies-integrity-for-contributors">Dependencies integrity for contributors</h3>
<ul>
<li>Be wary of any build scripts that use unusual repositories, plugins, or dependencies.
Dependency verification is not a guarantee of trustworthiness, it only ensures that what is used by the build matches expectations.</li>
</ul>
<h2 id="how-to-ensure-project-integrity">How to ensure project integrity?</h2>
<p>This is potentially a major effort, and the level of scrutiny will depend on many factors.
However, it’s important to understand that any time you run someone else’s code you are exposed to a potential security risk.</p>
<h3 id="project-integrity-for-maintainers-and-contributors">Project integrity for maintainers and contributors</h3>
<ul>
<li>Inspect the build scripts and any contributed code before running any tasks or importing a project into the IDE.
Even running <code class="language-plaintext highlighter-rouge">gradle help</code> could do something malicious.</li>
<li>Consider using throw away environments when running untrusted code, both locally and in a continuous integration environment.</li>
</ul>
<h2 id="conclusion">Conclusion</h2>
<p>Supply chain attacks are a sad reality as we showed in our recent <a href="/wrapper-attack-report">security report</a>.</p>
<p>The Gradle team will continue to look for ways to improve the security of the Gradle Build Tool and its community.
Please report any suspicious projects, wrappers, or distributions to <a href="mailto:security@gradle.com">us</a>.
However, in the end, security is the responsibility of every project and developer.
You should assess your risks, and needs.
And then act accordingly.</p>
<p>Let us know if you have any questions on our <a href="https://discuss.gradle.org/">forums</a> or <a href="https://gradle.com/slack-invite">Gradle Community Slack</a>, or start a discussion below.</p>
Plugin Portal Potential Data Exposure2022-08-24T00:00:00-04:00https://blog.gradle.org/portal-information-exposureLouis Jacomet
<p>On 16th August 2022, Gradle Plugin Portal and the Gradle Discourse forums were impacted by a security incident that could have led to exposure of the personal data of some Gradle community members.</p>
<p>No other services, hosted on <a href="https://gradle.org">gradle.org</a>, <a href="https://gradle.com">gradle.com</a>, or elsewhere were impacted.</p>
<h1 id="what-happened">What happened?</h1>
<p>An Amazon Web Services key granting access to database backups that contained personal information for a subset of the Gradle Plugin Portal and Discourse forum users was exposed in a Git commit.
This key was exposed for two hours before being revoked.</p>
<p>We believe it is unlikely that the exposure led to an unauthorized access of data, but we are taking actions and notifying impacted individuals out of caution and transparency.</p>
<h1 id="what-data-was-exposed">What data was exposed?</h1>
<p>We have inspected the database backups to determine what data could have been accessed.
The backups were from the development environment that contained data for the Gradle Plugin Portal and Discourse users.</p>
<p>We are emailing affected users to notify them specifically of this incident.
If you do not receive an email from us about this incident, you are not affected by it.</p>
<p>The personal data that could have been impacted by the incident likely varies depending on the user but could include information such as email address, display names, and for some individuals, hashed and salted passwords.
We have confirmed that no activity has occurred with respect to any account related to any of the hashed and salted passwords potentially impacted by the incident.
The following data could have been exposed:</p>
<h4 id="email-users">7133 display names, usernames and potential GitHub usernames and email addresses for all users that were present in the development database of the Gradle Plugin Portal</h4>
<ul>
<li>Display name and username are already public on the Plugin Portal or Discourse. So is the association with the GitHub username when using GitHub as the identity provider.</li>
<li>However, emails are not public on the Plugin Portal or Discourse.
If the database was downloaded by a third party, they would be able to link these 7000 Plugin Portal or Discourse usernames to an email address.</li>
</ul>
<h4 id="email-migration">3994 usernames and email addresses from a historical version of the Gradle Build Tool Forum</h4>
<ul>
<li>Usernames (mixture of handles and display names) are already public on our forums</li>
<li>However, email addresses are not public.
If the database was downloaded by a third party, they would be able to link these 4008 usernames to an email address.</li>
</ul>
<h4 id="password-unactivated">195 username, email and hashed and salted passwords for un-activated user accounts</h4>
<ul>
<li>Hashes were generated using bcrypt</li>
<li>None of these users have been activated since the incident</li>
<li>Only 2 of those hashed passwords match production users</li>
</ul>
<h1 id="what-data-remained-safe">What data remained safe?</h1>
<ul>
<li>None of the publishing keys for any plugin on the production Gradle Plugin Portal were exposed.</li>
<li>None of the Plugin Portal artifacts could be replaced.</li>
<li>None of the Discourse forums posts could be altered.</li>
</ul>
<h1 id="what-should-you-do-to-protect-yourself-from-data-abuse">What should you do to protect yourself from data abuse?</h1>
<ul>
<li>We recommend being extra cautious around Gradle-themed phishing attacks that may seek to target your status as a Gradle plugin author or Gradle forum user.
If you have any questions about whether a communication is authentically from Gradle, feel free to reach out to us at <code class="language-plaintext highlighter-rouge">security@gradle.com</code>.</li>
<li>We recommend using unique and challenging passwords for all of your accounts (Gradle-related or otherwise).
Best practice is to use password-manager generated unique passwords for each service.</li>
<li>Reach out to us if you have any questions or would like to change the email address of your account by contacting us at <code class="language-plaintext highlighter-rouge">plugin-portal-support@gradle.com</code>.</li>
</ul>
<h1 id="what-have-we-done-to-respond-to-the-incident">What have we done to respond to the incident?</h1>
<ul>
<li>Carried out incident response procedures, including investigating and mitigating the exposure.</li>
<li>Enabled Github Push Protection across all repositories organization-wide to prevent secret keys from being accidentally pushed to GitHub</li>
<li>Notified potentially affected community members</li>
<li>Stale pending user activations have been purged</li>
</ul>
<h1 id="what-will-we-do-to-prevent-further-incidents">What will we do to prevent further incidents?</h1>
<p>We are taking the following further steps to improve our security and avoid repeat incidents:</p>
<ul>
<li>Stopping passing credentials in command-line arguments for tests</li>
<li>Introducing retention policies on our database</li>
<li>Cleaning up the development and production databases, deleting unneeded data</li>
<li>Enabling S3 access logging account-wide by default</li>
<li>Encrypting database backups</li>
</ul>
<h1 id="incident-timeline">Incident Timeline</h1>
<dl>
<dt>2022.08.16 at 10:03 UTC</dt>
<dd>Commit with AWS access key and secret was pushed</dd>
<dt>2022.08.16 at 10:09 UTC</dt>
<dd>AWS notified Gradle of this disclosure and automatically applied a quarantine policy that prevents destructive actions from being taken with this key</dd>
<dt>2022.08.16 at 12:04 UTC</dt>
<dd>AWS key disabled by Gradle staff</dd>
<dt>2022.08.16 - 2022.08.23</dt>
<dd>Internal incident response</dd>
<dt>2022.08.24</dt>
<dd>Publication of this blog entry and notifications of affected users</dd>
</dl>
<h1 id="final-words">Final words</h1>
<p>We are sorry to have been in a position of potentially disclosing information entrusted to us.
We are using this incident as a way to improve our internal systems and security to reduce the likelihood of such an event happening again.</p>
Dealing with the Critical Log4j Vulnerability2021-12-13T00:00:00-05:00https://blog.gradle.org/log4j-vulnerabilityKyle Moore
<p>A critical remote code execution (RCE) vulnerability has been identified in the popular Apache Log4j logging library that affects versions 2.0 up to and including 2.14.1. This vulnerability has affected a very large number of JVM-based systems. For more information on the vulnerability itself, see <a href="https://nvd.nist.gov/vuln/detail/CVE-2021-44228">CVE-2021-44228</a>.</p>
<p><strong>Update (December 22, 2021)</strong>: Since the first post, two other vulnerabilities have been identified - <a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-45046">CVE-2021-45046</a> and <a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-45105">CVE-2021-45105</a> - so make sure to go over the different sections for updated instructions.</p>
<p>This vulnerability is being actively exploited. All Gradle users should assess whether their software projects are vulnerable and, if necessary, update to <a href="https://logging.apache.org/log4j/2.x/changes-report.html#a2.17.0">Log4j 2.17.0</a> or newer as soon as possible. We have <a href="#protecting">provided instructions below</a> on how to identify and prevent this vulnerability in your project.</p>
<p>We strongly recommended that you configure your Gradle build to reject any vulnerable version of Log4j using a <a href="https://docs.gradle.org/current/userguide/rich_versions.html#rich-version-constraints">dependency constraint</a>.</p>
<p>In addition to your project dependencies, we also recommend protecting your build dependencies as documented below.</p>
<p>Note that the Gradle Build Tool itself is <em>not</em> impacted by this vulnerability as it does not use Log4j. Gradle uses SLF4J and a custom logging implementation not susceptible to the vulnerable string substitution.</p>
<p>The <a href="https://docs.gradle.org/current/userguide/scala_plugin.html">Gradle Scala plugin</a> uses the Zinc Scala compiler that has a dependency on a vulnerable version of Log4j. However, in this case Gradle also supplies its own logging implementation and Log4j is not used by default.</p>
<blockquote>
<p>Updates to this post:</p>
<ul>
<li><a href="#2-upgrade-the-log4j-dependency-to-a-non-vulnerable-version">Updated</a> on December 14th</li>
<li><a href="#protecting-your-build-dependencies">Updated</a> on December 15th</li>
<li><a href="#2-upgrade-the-log4j-dependency-to-a-non-vulnerable-version">Updated</a> on December 22nd</li>
<li><a href="#protecting-plugin-portal-users">Updated</a> on December 30th</li>
</ul>
</blockquote>
<p><a name="protecting"></a></p>
<h2 id="protecting-your-project-dependencies">Protecting your project dependencies</h2>
<h3 id="1-identify-if-your-project-uses-a-vulnerable-log4j-version">1. Identify if your project uses a vulnerable Log4j version</h3>
<p>First, verify if your project uses the vulnerable Log4j version using the <a href="https://docs.gradle.org/current/userguide/viewing_debugging_dependencies.html#sec:listing_dependencies">dependencies report</a> or a <a href="https://scans.gradle.com/">Build Scan™</a>. See <a href="https://docs.gradle.org/current/userguide/viewing_debugging_dependencies.html#sec:identifying_reason_dependency_selection">viewing and debugging dependencies</a> for details.</p>
<p>All versions of <code class="language-plaintext highlighter-rouge">org.apache.logging.log4j:log4j-core</code> between 2.0 and 2.16.0 (inclusive) are vulnerable.</p>
<h3 id="2-upgrade-the-log4j-dependency-to-a-non-vulnerable-version">2. Upgrade the Log4j dependency to a non-vulnerable version</h3>
<p>Upgrade the Log4j dependency in the <code class="language-plaintext highlighter-rouge">dependencies</code> block of the build scripts for each subproject or in your <a href="https://docs.gradle.org/current/userguide/platforms.html#sub:version-catalog">version catalog</a> in the case you are using central declaration of dependencies.</p>
<p><strong>Update (December 14, 2021)</strong>: Log4j released <a href="https://logging.apache.org/log4j/2.x/changes-report.html#a2.16.0">2.16.0</a> which disables and removes support for the feature at the heart of the vulnerability. In some non-default configurations, software <a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-45046">could still be vulnerable with 2.15.0</a>. To be absolutely certain, you should update to 2.16.0. The instructions below have been modified to use 2.16.0.</p>
<p><strong>Update (December 22, 2021)</strong>: Log4j released <a href="https://logging.apache.org/log4j/2.x/changes-report.html#a2.17.0">2.17.0</a> which fixes <a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-45105">yet another vulnerability</a>. To be absolutely certain, you should update to 2.17.0. The instructions below have been modified to use 2.17.0.</p>
<p><a name="constraint"></a></p>
<h3 id="3-prevent-accidental-resolution-of-a-vulnerable-log4j-version-in-your-project">3. Prevent accidental resolution of a vulnerable Log4j version in your project</h3>
<p>Given the critical severity of this vulnerability, we recommend taking the additional step described below in order to prevent accidental inclusion of a vulnerable version. Note that even if you are not using Log4j directly, the vulnerable version may still be resolved transitively through one your dependencies.</p>
<p>Use the <a href="https://docs.gradle.org/current/userguide/rich_versions.html#rich-version-constraints">dependency constraints</a> feature to make sure that your project cannot resolve an impacted Log4j version by adding the following snippet to your Gradle build:</p>
<div class="language-groovy highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">dependencies</span> <span class="o">{</span>
<span class="n">constraints</span> <span class="o">{</span>
<span class="n">implementation</span><span class="o">(</span><span class="s2">"org.apache.logging.log4j:log4j-core"</span><span class="o">)</span> <span class="o">{</span>
<span class="n">version</span> <span class="o">{</span>
<span class="n">strictly</span><span class="o">(</span><span class="s2">"[2.17, 3["</span><span class="o">)</span>
<span class="n">prefer</span><span class="o">(</span><span class="s2">"2.17.0"</span><span class="o">)</span>
<span class="o">}</span>
<span class="n">because</span><span class="o">(</span><span class="s2">"CVE-2021-44228, CVE-2021-45046, CVE-2021-45105: Log4j vulnerable to remote code execution and other critical security vulnerabilities"</span><span class="o">)</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>The constraint will not be activated unless log4j-core appears in the dependency graph. The constraint will either forcefully upgrade the dependency to at least 2.17.0 or fail the build if the strict version constraint cannot be satisfied.</p>
<p>Note that using the <code class="language-plaintext highlighter-rouge">implementation</code> configuration here will cover the default setup of a Java library or application. But if you have custom configurations or more advanced setup, you should also add this constraint to additional configurations.</p>
<p>In addition, if you publish your library with such a constraint defined with <a href="https://docs.gradle.org/current/userguide/publishing_gradle_module_metadata.html">Gradle Module Metadata</a>, it will also cause any builds consuming your library to fail if they attempt to resolve a vulnerable version of log4j-core.</p>
<h3 id="4-prevent-using-a-vulnerable-log4j-version-organization-wide">4. Prevent using a vulnerable Log4j version organization-wide</h3>
<p>Your organization may leverage shared plugins that are applied to all projects. In this case, you can also apply the constraint described above to all the projects in the organization.</p>
<p>If you use <a href="https://docs.gradle.org/current/userguide/custom_plugins.html#sec:precompiled_plugins">precompiled script plugins</a>, simply copy the above <a href="#constraint">snippet</a> to the script applied to all your JVM projects. If you use binary plugins, here is the Java code equivalent to the DSL snippet:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">project</span><span class="o">.</span><span class="na">getDependencies</span><span class="o">().</span><span class="na">constraints</span><span class="o">(</span><span class="n">constraints</span> <span class="o">-></span> <span class="o">{</span>
<span class="n">constraints</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="s">"implementation"</span><span class="o">,</span> <span class="s">"org.apache.logging.log4j:log4j-core"</span><span class="o">,</span> <span class="n">c</span> <span class="o">-></span> <span class="o">{</span>
<span class="n">c</span><span class="o">.</span><span class="na">version</span><span class="o">(</span><span class="n">v</span> <span class="o">-></span> <span class="o">{</span>
<span class="n">v</span><span class="o">.</span><span class="na">strictly</span><span class="o">(</span><span class="s">"[2.17, 3["</span><span class="o">);</span>
<span class="n">v</span><span class="o">.</span><span class="na">prefer</span><span class="o">(</span><span class="s">"2.17.0"</span><span class="o">);</span>
<span class="o">});</span>
<span class="n">c</span><span class="o">.</span><span class="na">because</span><span class="o">(</span><span class="s">"CVE-2021-44228, CVE-2021-45046, CVE-2021-45105: Log4j vulnerable to remote code execution and other critical security vulnerabilities"</span><span class="o">);</span>
<span class="o">});</span>
<span class="o">});</span>
</code></pre></div></div>
<h2 id="protecting-your-build-dependencies">Protecting your build dependencies</h2>
<p><del><strong>Update (December 15, 2021)</strong>: You do not need to apply this to Gradle 7.3.2 and above. Gradle automatically requires the version of Log4J to be 2.16.0 or higher.</del></p>
<p><strong>Update (December 22, 2021)</strong>: You do not need to apply this to Gradle 7.3.3 and above. Gradle automatically requires the version of Log4J to be 2.17.0 or higher. Gradle 6.9.2 also does this for users still on the 6.x line.</p>
<p>In addition to project dependencies, your project probably uses either internal or third-party Gradle plugins. These plugins also have their own dependencies that may accidentally bring a vulnerable Log4j dependency to the build classpath.</p>
<p>In other words, your build logic may be vulnerable in the same way that your production code. While such vulnerabilities are likely harder to exploit, you can also protect your build dependencies with the snippet below:</p>
<div class="language-groovy highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">buildscript</span> <span class="o">{</span>
<span class="n">dependencies</span> <span class="o">{</span>
<span class="n">constraints</span> <span class="o">{</span>
<span class="n">classpath</span><span class="o">(</span><span class="s2">"org.apache.logging.log4j:log4j-core"</span><span class="o">)</span> <span class="o">{</span>
<span class="n">version</span> <span class="o">{</span>
<span class="n">strictly</span><span class="o">(</span><span class="s2">"[2.17, 3["</span><span class="o">)</span>
<span class="n">prefer</span><span class="o">(</span><span class="s2">"2.17.0"</span><span class="o">)</span>
<span class="o">}</span>
<span class="n">because</span><span class="o">(</span><span class="s2">"CVE-2021-44228, CVE-2021-45046, CVE-2021-45105: Log4j vulnerable to remote code execution and other critical security vulnerabilities"</span><span class="o">)</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>The snippet should be applied to the <code class="language-plaintext highlighter-rouge">buildscript</code> block in each build script and also to the settings.gradle(.kts) file, and ensures only Log4j 2.17.0 and above are resolvable as build dependencies. The statement must be at the top of the file.</p>
<h2 id="protecting-plugin-portal-users">Protecting Plugin Portal users</h2>
<p>Given the severity of the initial Log4j vulnerability, the Gradle team wanted to improve the situation for users of the Plugin Portal.
We are taking steps to make sure that no new plugin can have a dependency on a vulnerable Log4j version.
The following changes are available already and will be made mandatory in a later update.</p>
<p>As a Gradle plugin author, it is possible that you have either direct, or transitive dependencies on the vulnerable Log4j versions.
In order to protect your plugin users, Gradle has added new validation rules to its <code class="language-plaintext highlighter-rouge">plugin-publish</code> plugin.</p>
<p>We have released <a href="https://plugins.gradle.org/plugin/com.gradle.plugin-publish/0.19.0">version 0.19.0 of the Plugin Publish Plugin</a> which automatically detects vulnerable Log4j plugin dependencies and, if any are found, blocks the plugin publication by failing the build.
There is no automated upgrade as normally a Gradle plugin does not need Log4j since the Gradle runtime does not do its logging with this library.
It is the job of the plugin author to fix the problem by removing the dependency or upgrading it.</p>
<p>Using this version of the Plugin Publish Plugin will become mandatory in the near future, by having the Plugin Portal reject any publications done with older versions of the plugin.</p>
<h2 id="gradle-enterprise-products">Gradle Enterprise products</h2>
<p>Several Gradle Enterprise products <a href="https://security.gradle.com/advisory/2021-11">were impacted</a> by the Log4j vulnerability.</p>
<p>New versions of Gradle Enterprise, Test Distribution Agent and Build Cache Node were released December 13, 2021.</p>
<p><strong>Update (December 22, 2021)</strong>: Gradle Enterprise 2021.4 upgrades Log4j to 2.17.0</p>
<h2 id="feedback">Feedback</h2>
<p>Let us know if you have any questions on our <a href="https://discuss.gradle.org/">forums</a> or <a href="https://gradle.com/slack-invite">Gradle Community Slack</a>.</p>
Plugin Portal Security CVE-2020-75992020-03-27T00:00:00-04:00https://blog.gradle.org/plugin-portal-updateSterling Greene
<h2 id="important-update-when-publishing-plugins-to-the-plugin-portal">Important update when publishing plugins to the Plugin Portal</h2>
<p>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.</p>
<p>In response, we’ve published a new version of the <code class="language-plaintext highlighter-rouge">com.gradle.plugin-publish</code> plugin that contains an update to mitigate this security vulnerability.</p>
<p>Please upgrade <a href="https://plugins.gradle.org/plugin/com.gradle.plugin-publish"><code class="language-plaintext highlighter-rouge">com.gradle.plugin-publish</code> plugin</a> to version <code class="language-plaintext highlighter-rouge">0.11.0</code>. Old versions of the <code class="language-plaintext highlighter-rouge">com.gradle.plugin-publish</code> plugin will <strong>no longer work</strong>. If you do not publish plugins to the <a href="https://plugins.gradle.org/">Plugin Portal</a>, you do not need to do anything.</p>
<p>We also recommend that builds handling sensitive information (like publishing builds) do not run with elevated log levels (like <code class="language-plaintext highlighter-rouge">--debug</code> 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 (<a href="https://docs.travis-ci.com/user/best-practices-security/#recommendations-on-how-to-avoid-leaking-secrets-to-build-logs">as an example, Travis CI</a>). Like other software, build maintainers and plugin authors need to keep in mind the types of information that may be logged.</p>
<p>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.</p>
<h3 id="discovery-of-the-vulnerability">Discovery of the Vulnerability</h3>
<p>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 <code class="language-plaintext highlighter-rouge">info</code> level logging is enabled. This is an information disclosure vulnerability (<a href="https://cwe.mitre.org/data/definitions/532.html">CWE-532: Insertion of Sensitive Information into Log File</a>) for the Plugin Publish Plugin and is tracked by <a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-7599">CVE-2020-7599</a>.</p>
<p>Thanks to <a href="https://github.com/DanielThomas">Danny Thomas</a> from Netflix for reporting this issue to us.</p>
<p>When a plugin is published to the Plugin Portal, a <a href="https://docs.aws.amazon.com/AmazonS3/latest/dev/PresignedUrlUploadObject.html">pre-signed AWS S3 URL</a> is passed to the <code class="language-plaintext highlighter-rouge">com.gradle.plugin-publish</code> 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 (<code class="language-plaintext highlighter-rouge">--info</code> or <code class="language-plaintext highlighter-rouge">--debug</code>), 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.</p>
<p>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 <code class="language-plaintext highlighter-rouge">debug</code> level logging can expose sensitive information about your infrastructure, passwords or internal web endpoints. This vulnerability was made possible with builds that ran with <code class="language-plaintext highlighter-rouge">info</code> level logging enabled.</p>
<h3 id="remediation-and-investigation">Remediation and Investigation</h3>
<p>After our investigation, we found no maliciously overwritten artifacts.</p>
<p>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 <code class="language-plaintext highlighter-rouge">com.gradle.plugin-publish</code> plugin works, the URL needs to remain valid for some amount of time to allow for all of the artifacts to be published.</p>
<p>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.</p>
<p>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.</p>
<p>The artifacts consisted of</p>
<ul>
<li>non-executable artifacts, like source, javadoc and groovydoc that did not contain class files (4)</li>
<li>artifacts that were mismatched due to an earlier, unrelated, security investigation (2)</li>
<li>artifacts that were produced by a non-public build (2)</li>
<li>an artifact that was intentionally changed while investigating this vulnerability</li>
<li>a jar file that contained only timestamp differences when built locally</li>
<li>a pom file with no suspicious content</li>
<li>an invalid jar file</li>
</ul>
<p>None of the artifacts appear to be different in a meaningful way or could have been compromised for a malicious purpose.</p>
<p>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.</p>
<h3 id="has-the-problem-been-patched-what-version-should-i-upgrade-to">Has the problem been patched? What version should I upgrade to?</h3>
<p>We have published a new version of the <code class="language-plaintext highlighter-rouge">com.gradle.plugin-publish</code> plugin that reduces the log level for the pre-signed URL. Please upgrade <code class="language-plaintext highlighter-rouge">com.gradle.plugin-publish</code> to version <code class="language-plaintext highlighter-rouge">0.11.0</code>. Previous versions of this plugin <strong>no longer work</strong> and will be rejected by the Plugin Portal.</p>
<p>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 <code class="language-plaintext highlighter-rouge">--debug</code> will still expose the pre-signed URL. Internal JDK logging will log all HTTP requests–not just the artifact URLs.</p>
<p>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.</p>
<h3 id="i-cant-upgrade-is-there-anything-i-can-do">I can’t upgrade. Is there anything I can do?</h3>
<p>We’re requiring that everyone update to the latest version of the <code class="language-plaintext highlighter-rouge">com.gradle.plugin-publish</code> plugin. This version should work for anyone using Gradle 3.0 and above.</p>
<p>If you run into problems upgrading, please let us know with an <a href="https://github.com/gradle/gradle/issues/new/choose">issue</a>.</p>
<h3 id="for-more-information">For more information</h3>
<p>For security related issues, please email us at <a href="mailto:security@gradle.com">security@gradle.com</a>.</p>
<p>For non-security related issues, please open an issue on <a href="https://github.com/gradle/gradle/issues/new/choose">Github</a>.</p>
Verifying Gradle Wrappers with GitHub Actions2020-02-06T00:00:00-05:00https://blog.gradle.org/gradle-wrapper-checksum-verification-github-actionJonathan Leitschuh
<p><img src="images/verify-wrapper-action/wrapper-validation-status-check.png" alt="Pull Request Status Check with new 'Validate Gradle Wrapper / Validation' successful status" /></p>
<p>We are proud to announce the release of the new
<a href="https://github.com/marketplace/actions/gradle-wrapper-validation">Gradle Wrapper Validation GitHub Action</a>.</p>
<h2 id="gradle-wrapper-in-open-source">Gradle Wrapper in Open Source</h2>
<p>The <a href="https://docs.gradle.org/current/userguide/gradle_wrapper.html"><code class="language-plaintext highlighter-rouge">gradle-wrapper.jar</code></a>
is a binary blob of executable code that is checked into nearly
<a href="https://github.com/search?l=&q=filename%3Agradle-wrapper.jar&type=Code">2.8 Million GitHub Repositories</a>.</p>
<p>Searching across GitHub you can find many pull requests (PRs) with helpful titles like ‘Update to Gradle xxx’.
Many of these PRs are contributed by individuals outside of the organization maintaining the project.</p>
<p>Maintainers are grateful for these kinds of contributions as it takes an item off of their backlog.
But there are security implications of accepting changes to the Gradle Wrapper binary from external contributors that may not be apparent.
An attacker could take advantage of the trust the open source community has by
hiding malicious code inside the Gradle Wrapper.
A malicious <code class="language-plaintext highlighter-rouge">gradle-wrapper.jar</code> could download, install and execute arbitrary code while otherwise behaving like
a completely normal <code class="language-plaintext highlighter-rouge">gradle-wrapper.jar</code>.</p>
<p>Such an attack could be easily missed as the diff to the <code class="language-plaintext highlighter-rouge">gradle-wrapper.jar</code> looks like this.</p>
<p><img src="images/verify-wrapper-action/binary-wrapper-file-diff.png" alt="Image of a GitHub Diff of Gradle Wrapper displaying text 'Binary file not shown.'" /></p>
<h2 id="verifying-the-gradle-wrapper">Verifying the Gradle Wrapper</h2>
<p>We have created a
<a href="https://github.com/marketplace/actions/gradle-wrapper-validation">simple GitHub Action</a>
that can be applied to any GitHub repository.
This action will verify that any and all <code class="language-plaintext highlighter-rouge">gradle-wrapper.jar</code> files in the repository match an
<a href="https://gradle.org/release-checksums/">official SHA-256 checksum</a>.
If any file does not match, the action will fail.</p>
<p>Additionally, the action will detect any <a href="https://en.wikipedia.org/wiki/Homoglyph">homoglyph</a> variants of a file named <code class="language-plaintext highlighter-rouge">gradle-wrapper.jar</code>.
The goal is to prevent difficult to spot homoglyph attacks,
like renaming the <code class="language-plaintext highlighter-rouge">gradle-wrapper.jar</code> file to <code class="language-plaintext highlighter-rouge">gradlе-wrapper.jar</code> (which uses a Cyrillic <code class="language-plaintext highlighter-rouge">е</code> instead of <code class="language-plaintext highlighter-rouge">e</code>).</p>
<h2 id="securing-your-project">Securing Your Project</h2>
<p>GitHub actions are free to use for open-source and are automatically enabled by default on almost all repositories.
You can find out more about how to add this action to your GitHub repository
<a href="https://github.com/marketplace/actions/gradle-wrapper-validation#usage">here</a>.</p>
<h3 id="existing-users">Existing Users</h3>
<p>This action has already been contributed to some of the most popular Gradle based projects on GitHub including but not limited to:</p>
<ul>
<li><a href="https://github.com/ReactiveX/RxJava">ReactiveX/RxJava</a></li>
<li><a href="https://github.com/ReactiveX/RxAndroid">ReactiveX/RxAndroid</a></li>
<li><a href="https://github.com/junit-team/junit5-samples">junit-team/junit5</a></li>
<li><a href="https://github.com/JakeWharton/butterknife">JakeWharton/butterknife</a></li>
<li><a href="https://github.com/google/flexbox-layout">google/flexbox-layout</a></li>
<li><a href="https://github.com/ktorio/ktor">ktorio/ktor</a></li>
<li><a href="https://github.com/facebook/fresco">facebook/fresco</a></li>
<li><a href="https://github.com/facebook/flipper">facebook/flipper</a></li>
<li><a href="https://github.com/mockito/mockito">mockito/mockito</a></li>
<li><a href="https://github.com/jhipster/generator-jhipster">jhipster/generator-jhipster</a></li>
<li><a href="https://github.com/apache/groovy">apache/groovy</a></li>
<li><a href="https://github.com/apache/lucene-solr">apache/lucene-solr</a></li>
</ul>
<p>And <a href="https://github.com/search?l=YAML&q=gradle%2Fwrapper-validation-action&s=indexed&type=Code">many more</a>!</p>
<h3 id="reporting-failures">Reporting Failures</h3>
<p>If this GitHub action fails because a <code class="language-plaintext highlighter-rouge">gradle-wrapper.jar</code> doesn’t match one of our published SHA-256 checksums,
we highly recommend that you reach out to us at <a href="mailto:security@gradle.com">security@gradle.com</a>.</p>
<p>If you’re curious and want to explore what the differences are between the <code class="language-plaintext highlighter-rouge">gradle-wrapper.jar</code> in your possession
and one of our valid releases, you can compare them using this online utility: <a href="https://try.diffoscope.org/">DiffScope</a>.</p>
<h2 id="resources">Resources</h2>
<p>To learn more about verifying the Gradle Wrapper JAR locally (ie. without using GitHub Actions), see our
<a href="https://docs.gradle.org/current/userguide/gradle_wrapper.html#wrapper_checksum_verification">documentation on the topic</a>.</p>
Decommissioning HTTP for Gradle Services2019-10-17T00:00:00-04:00https://blog.gradle.org/decommissioning-httpJonathan Leitschuh
<p>Starting in January 2020, <strong>Gradle services will only serve requests made with HTTPS</strong>. From that point on,
all requests made with HTTP will be denied and any builds and artifact mirrors that use a Gradle URL with the non-secure
HTTP protocol will fail.</p>
<p>If you are proxying our services through your own artifact servers like Artifactory or Nexus, you will need
to ensure that you update your mirror configurations so they are using HTTPS instead of HTTP.</p>
<h2 id="gradle-services">Gradle Services</h2>
<p>This change will impact the following services.</p>
<h3 id="plugin-portal">Plugin Portal</h3>
<p>By default, the Gradle build tool uses HTTPS when resolving plugins from the Plugin Portal.
You should be unaffected if you do not <a href="https://docs.gradle.org/current/userguide/plugins.html#sec:plugin_management">declare a custom plugin repository</a>.</p>
<p>If your organization <a href="https://plugins.gradle.org/docs/mirroring">mirrors the Plugin Portal</a>
from URL <code class="language-plaintext highlighter-rouge">plugins.gradle.org/m2/*</code>, you should check that your mirror is using HTTPS.</p>
<h3 id="gradle-distributions">Gradle Distributions</h3>
<p>Since Gradle 1.2, the Gradle wrapper has used HTTPS to download Gradle distributions. You should be unaffected if your <code class="language-plaintext highlighter-rouge">gradle-wrapper.properties</code> uses a HTTPS URL.</p>
<p>Gradle distributions are served from the following URLs:</p>
<ul>
<li><code class="language-plaintext highlighter-rouge">services.gradle.org</code></li>
<li><code class="language-plaintext highlighter-rouge">downloads.gradle.org</code></li>
<li><code class="language-plaintext highlighter-rouge">downloads.gradle-dn.com</code></li>
</ul>
<p>If your organization mirrors Gradle distributions from any of these URLs, you should check that your mirror is using HTTPS.</p>
<h3 id="other-gradle-software">Other Gradle software</h3>
<p>Other Gradle, Inc. produced software is published to an Artifactory repository, such as the Gradle Tooling API. Most builds do not use this repository unless they are building tooling that integrates with Gradle (like IntelliJ IDEA).</p>
<p>The Gradle Artifactory repository is available at <code class="language-plaintext highlighter-rouge">repo.gradle.org</code>.</p>
<h2 id="gradle-build-tool">Gradle Build Tool</h2>
<p><a href="https://docs.gradle.org/6.0-rc-1/release-notes.html#security">Gradle 6.0</a> deprecates the use of HTTP in build scripts to download resources and artifacts without an an explict opt-in.</p>
<p>For users that require the use of HTTP, Gradle has several new APIs to continue to allow HTTP on a case-by-case basis.</p>
<h2 id="timeline">Timeline</h2>
<p>To ease the transition for our users, this change is coming in a few phases.</p>
<table>
<thead>
<tr>
<th>When</th>
<th>What’s changing?</th>
</tr>
</thead>
<tbody>
<tr>
<td><del>October 29th, 2019</del></td>
<td>Gradle will begin redirecting from HTTP to HTTPS.</td>
</tr>
<tr>
<td><del>November 14th, 2019</del></td>
<td>Disable HTTP for 24 hours and permanently drop support for TLSv1. <a href="https://status.gradle.com/incidents/q2vq49fndxg0">Postmortem</a>.</td>
</tr>
<tr>
<td><del>January 15th, 2020</del></td>
<td>HTTP requests to Gradle resources will be <em>denied</em>. Only HTTPS will be supported.</td>
</tr>
<tr>
<td><del>February 15th, 2020</del></td>
<td>Enable <a href="https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security">HSTS</a> for <code class="language-plaintext highlighter-rouge">gradle.com</code> and <code class="language-plaintext highlighter-rouge">gradle.org</code>. This change will only impact browsers.</td>
</tr>
</tbody>
</table>
<h2 id="users-most-likely-to-be-impacted">Users most likely to be impacted</h2>
<p>As a part of this effort, we spent some time analyzing the data from our CDN logs to determine the size of the impact
this change would have on our users.</p>
<p>These percentages represent a sampling of our traffic over a 72 hour period.</p>
<table>
<thead>
<tr>
<th>Service</th>
<th style="text-align: right">HTTP %</th>
</tr>
</thead>
<tbody>
<tr>
<td>plugins.gradle.org/m2/*</td>
<td style="text-align: right">0.72%</td>
</tr>
<tr>
<td>services.gradle.org</td>
<td style="text-align: right">5.77%</td>
</tr>
<tr>
<td>downloads.gradle.org</td>
<td style="text-align: right">23.87%</td>
</tr>
<tr>
<td>downloads.gradle-dn.com</td>
<td style="text-align: right">9.76%</td>
</tr>
<tr>
<td>repo.gradle.org</td>
<td style="text-align: right">9.53%</td>
</tr>
</tbody>
</table>
<p>Breaking down the traffic for services.gradle.org by user agent, we can clearly see that
users of JFrog’s Artifactory are most likely to be impacted by this change.</p>
<p><img src="/images/http-decommission/HTTP_by_agent_services_gradle_org.png" alt="HTTP by Agent for services.gradle.org" /></p>
<p>Similarly, we can see while our biggest user of <code class="language-plaintext highlighter-rouge">services.gradle.org</code> is a Java user agent, Artifactory is our
second largest and is more likely to be using <code class="language-plaintext highlighter-rouge">HTTP</code> than any other User Agent.</p>
<p><img src="/images/http-decommission/HTTP_vs_HTTPS_for_services_gradle_org.png" alt="HTTP vs HTTPS for services.gradle.org by Agent" /></p>
<p>Using this data, we’ve determined that 16% of all Nexus requests, and 11% of all Artifactory requests are using HTTP instead of HTTPS.</p>
<p><strong>We recommend that you audit your corporate artifact mirrors to ensure that they are using HTTPS instead of HTTP.</strong></p>
<h2 id="why-are-we-doing-this">Why are we doing this?</h2>
<p><a href="https://medium.com/@jonathan.leitschuh/want-to-take-over-the-java-ecosystem-all-you-need-is-a-mitm-1fc329d898fb?source=friends_link&sk=3c99970c55a899ad9ef41f126efcde0e"><img src="/images/http-decommission/build_mitm.png" alt="mitm_build" /></a></p>
<p>At the beginning of June 2019, before joining the Gradle team, I
<a href="https://medium.com/@jonathan.leitschuh/want-to-take-over-the-java-ecosystem-all-you-need-is-a-mitm-1fc329d898fb?source=friends_link&sk=3c99970c55a899ad9ef41f126efcde0e">publicly disclosed my research</a>
into how many of the most popular projects across the JVM ecosystem had been resolving their dependencies over HTTP
instead of HTTPS.</p>
<p>When <a href="https://www.sonatype.com/">Sonatype</a>, the maintainers of <a href="https://search.maven.org/">Maven Central</a>,
analyzed their traffic over a month, they determined that 25% of Maven Central downloads were still using HTTP.</p>
<p>As a result of these findings, Gradle is participating in an industry-wide initiative to decommission support for HTTP from all major artifact servers starting on or near January 15th, 2020.</p>
<p>As of the publication of this blog post, these organizations are also participating and have posted announcements:</p>
<ul>
<li><a href="https://central.sonatype.org/articles/2019/Apr/30/http-access-to-repo1mavenorg-and-repomavenapacheorg-is-being-deprecated/">Sonatype Maven Central</a></li>
<li><a href="https://jfrog.com/blog/secure-jcenter-with-https/">JFrog JCenter</a></li>
<li><a href="https://spring.io/blog/2019/09/16/goodbye-http-repo-spring-use-https">Pivotal Spring</a></li>
</ul>