Skip to main content

Maven 3.8.1にアップグレードすべき理由

blog feature maven click

2021年7月19日

0 分で読めます

Javaエコシステムで開発を行い、古いバージョンのMavenでアプリケーションを構築している方に、ぜひお読みいただきたい内容です。

mvn -versionと入力して、Mavenのバージョンを確認してください。Maven 3.6.3以前の古いバージョンをまだお使いの場合は、セキュリティ上の理由から、必ずバージョン3.8.1にアップグレードしてください。Maven 3.8.1の実行にはJava 7以降が必要です。

幸い、JVM Ecosystem report 2021によると、Java 6以前を使用している人は多くありません。一方で、Mavenを使っている人は多いため、アップグレードしないと、エコシステムの広範囲に深刻な問題が生じる可能性があります。

古いMavenバージョンにおけるHTTPリポジトリの問題

Maven 3.8.1より前のバージョンでは、HTTPを使ってカスタムリポジトリに接続できました。この問題はJonathan Leitschuhによって報告され、CVE-2021-26291に記載されています。Maven 3.8.1のリリースノートでは、Mavenは次の3つの問題を挙げています。

  • HTTP経由でカスタムリポジトリを利用することによる中間者攻撃(MITM攻撃)

  • カスタムリポジトリが放棄されたドメインを使用している場合の、ドメイン乗っ取り

  • カスタムリポジトリへのリダイレクトによるダウンロードの乗っ取りの可能性

リポジトリのダウンロード順序は、Repository Order Pageに次のように記載されています。

  1. 有効な設定:

    1. グローバル(${maven.home}/conf/settings.xmlで定義)

    2. ユーザー(${user.home}/.m2/settings.xmlで定義)

  2. ローカルの有効なビルドPOM:

    1. ローカルのpom.xml(プロジェクトのpom.xmlファイル)

    2. 親POMを再帰的にたどる

    3. Super POM

  3. アーティファクトへの依存関係パス上にある有効なPOM

つまり、設定ファイルを確認した後、Mavenはpom.xml内のリポジトリを探します。最終的にSuper POMにたどり着き、そこにMaven Centralの場所が定義されています。

アーティファクトへの依存関係パス上にある有効なPOM

3番目の手順は少し分かりにくいので、説明してみましょう。

依存関係(depA)が1つあり、カスタムリポジトリ(myRepo1)も宣言されているプロジェクトのPOMファイルを見てみましょう。

Mavenは最初にローカルのpom.xmlを確認するため、Maven Centralに進む前にmyRepo1でdepAを探します。

depAが依存関係(depB)を持ち、以下のようにdepAにmyRepo2がある場合、depBはどこからダウンロードされるでしょうか。

リポジトリ myRepo1 と myRepo2 にまたがり、依存関係 depA と depB を介してリンクされた Maven プロジェクトの pom.xml ファイルを示す図。

depBをダウンロードする際、MavenはまずプロジェクトPOM(リポジトリ順序の2a、ローカルのpom.xml)にあるmyRepo1を確認します。次に親POMを順にたどり、Super POMを経由してMaven Centralまで確認します。パッケージdepBがMaven Centralにない場合は、myRepo2からダウンロードします。

これはMavenの機能であり、パッケージがMaven Centralに公開されていない場合に有効です。ただし、ほかの理由でMaven Centralを利用できない場合もあります。

これは想定外かもしれませんが、さらに重要なのは、Maven 3.8.1より前のバージョンではHTTPリポジトリが許可されていることです。

Maven Centralには、HTTP経由のカスタムリポジトリを参照するPOMファイルがあります。Maven Central上のPOMファイルは変更できないため、開発者が、推移的依存関係によって追加された外部リポジトリにHTTPで接続していることに気付かず、MITM攻撃の標的になる可能性があります。

Maven 3.8.1ではHTTPSがデフォルト

前述の問題を軽減するため、Mavenは外部HTTPリポジトリをデフォルトでブロックすることにしました。これは、ミラー設定に<blocked>フィールドを追加し、グローバル設定ファイル${maven.home}/conf/settings.xmlに次のミラーを指定することで実現します。

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

その結果、Mavenで新たに構築するアプリケーションは、HTTPではなくHTTPSを使って外部リポジトリに接続するようになります。HTTPSでは、クライアントが要求したサーバーと通信していることが保証されるためです。これにより、MITM攻撃を大幅に防止できます。

localhostやファイルリポジトリへのHTTP接続は、引き続き許可される点にご注意ください。

詳しく知りたい方は、Jonathan Leitschuhが2019年に執筆した優れたInfoSec記事「Want to take over the Java ecosystem? All you need is a MITM!」をご覧ください。

アップグレード方法

まず、Maven 3.8.1以降をダウンロードして、アプリケーションを再ビルドしてください。また、pom.xmlファイルでリポジトリを定義している場合は、HTTPSのURLに修正してください。依存関係のいずれかでHTTPリポジトリが定義されていると、エラーが発生します。まず、そのHTTPリポジトリのURLをHTTPSに置き換えた新しいバージョンのライブラリがないか確認してください。

企業によっては、社内リポジトリを使用している場合があります。こうしたリポジトリがHTTPSではなくHTTPのままだと、Maven 3.8.1でのビルドが失敗します。最善の解決策は、一度だけ投資して、これらのリポジトリがHTTPSを使用するようにすることです。また、これはミラー設定だけの問題なので、必要に応じて変更できます。独自のミラー設定を${user.home}/.m2/settings.xmlに作成するか、グローバルのsettings.xmlを変更してください。

ソフトウェア開発では、多くの依存関係を利用します。推移的依存関係を扱う際には、これらが信頼の連鎖を形成していることを忘れてはいけません。適切なパッケージを選び、依存関係を適時アップグレードしてください。同様に、システムへの悪意あるパッケージの侵入を防ぐため、使用するツールも常に最新の状態に保つことが不可欠です。

MavenとJavaのセキュリティについてさらに読む

開発者に愛され、セキュリティチームから信頼される。

Snykの開発者ファーストのツールは、ガバナンスやコンプライアンスのニーズに応える、統合された自動化セキュリティを提供します。