Skip to main content

Why you should upgrade to Maven version 3.8.1

Escrito por:
wordpress-sync/blog-feature-maven-click

19 de julho de 2021

0 minutos de leitura

If you are working in the Java ecosystem and building your applications with an older Maven version, this message is for you.

Check your Maven version by typing mvn -version! If you are still running on an old Maven version like 3.6.3 or below you definitely need to upgrade to version 3.8.1 because of security reasons. Be aware that to run Maven 3.8.1, Java 7+ is required.

Luckily we found out in the JVM Ecosystem report 2021 that not many people work with Java 6 or below. We do see that a lot of people use Maven so not upgrading can end up in serious issues for a large part of the ecosystem.

The problem with HTTP repositories in older Maven versions

Maven versions prior to 3.8.1 allowed users to connect to custom repositories using HTTP. This is reported by Jonathan Leitschuh and documented in CVE-2021-26291. From the release notes of Maven 3.8.1, Maven distinguished three separate issues:

  • A man-in-the-middle attack (MITM Attack) due to the use of custom repositories over HTTP

  • Domain hijacking when custom repositories are using abandoned domains

  • Possible hijacking of downloads by redirecting to custom repositories

The order for downloading repositories is described on the Repository Order Page as follows:

  1. Effective settings:

    1. Global (defined in the ${maven.home}/conf/settings.xml)

    2. User (defined in ${user.home}/.m2/settings.xml)

  2. Local effective build POM:

    1. Local pom.xml (the project pom.xml file)

    2. Parent POM’s recursively

    3. Super POM

  3. Effective POMs from dependency path to the artifact

This means that after looking at the settings files, Maven looks for repositories in the pom.xml. This ends in the Super POM where the location to Maven Central is defined.

Effective POMs from dependency path to the artifact

The third step is somewhat tricky, but let me try to explain this:

Let’s take a look at a project POM file that has one dependency (depA) and also declared a custom repository (myRepo1).

Maven will first look in myRepo1 for depA before going to Maven central because it looks at the local pom.xml first.

If the depA has a dependency (depB) and depA has a myRepo2 (like below), where will depB be downloaded from?

wordpress-sync/blog-upgrade-maven

To download depB, Maven will first look at myRepo1 because it is in the project POM (2a of the repository order, local pom.xml). Next, it will go to the parent POM all the way up to Maven Central via the Super POM. If the package depB is NOT available at Maven Central it will download the package from myRepo2.

This is a feature of Maven and valid for when the package is not published on Maven Central. However, it can also be that Maven Central is not available for other reasons.

This might not be what you expect, and more importantly, Maven allows HTTP repositories in versions prior to 3.8.1.

There are POM files on Maven Central that contain references to custom repositories over HTTP. POM files on Maven central are immutable, so it can easily be that developers are unaware that they connect to an external repository over HTTP introduced by a transitive dependency, making them a possible target to a MITM attack.

HTTPS by default in Maven version 3.8.1

To mitigate the problems discussed above, Maven decided to block external HTTP repositories by default. This is done by adding a <blocked> field in the mirror configuration and providing the following mirror to your global setting located at ${maven.home}/conf/settings.xml.

1<mirror>
2      <id>maven-default-http-blocker</id>
3      <mirrorOf>external:http:*</mirrorOf>
4      <name>Pseudo repository to mirror external repositories initially using HTTP.</name>
5      <url>https://0.0.0.0/</url>
6      <blocked>true</blocked>
7</mirror>

The result is that new applications built with Maven will not connect to external repositories using HTTP but only HTTPS. This is because HTTPS guarantees that the client is communicating with the requested server. This prevents MITM attacks to a great extent.

Note that HTTP connections to localhost and file repositories are still allowed.

Jonathan Leitschuh wrote a great InfoSec article, “Want to take over the Java ecosystem? All you need is a MITM!” in 2019 if you want to learn more.

How to upgrade

First of all, you need to download Maven version 3.8.1 or higher and rebuild your application. Next to that, if you have a repository defined in your pom.xml file, please fix it so it is an HTTPS URL. If an HTTP repository is defined in one of your dependencies, you will get an error. First, search for newer versions of that library that replaced the HTTP repository url with an HTTPS version.

In some examples, companies use internal repositories. These may still be on HTTP rather than HTTPS and that will break your building process with Maven version 3.8.1. The best solution is to make a one-time investment and ensure these repositories use HTTPS. Alternatively, this is just a mirror setting and can be changed if needed. You can create your own mirror setting in your ${user.home}/.m2/settings.xml or change the global settings.xml.

We use a lot of dependencies when developing software. We shouldn’t take this for granted, as this is all a chain of trust when we have to deal with transitive dependencies. Make sure to pick the correct package and upgrade your dependencies in time. Equally, it is essential to upgrade the tooling we use to prevent malicious packages in our system.

Read more about Maven and Java security