お知らせ loggers

【12/31更新】Log4Jの使用や使用中バージョンの調べ方・確認方法

Log4J2に関するRCE脆弱性(CVE-2021-44228)が世界的な問題となっています。『スッキリわかるJava入門』で学ばれエンジニアとしてご活躍中の方の中には、自身が運用中のシステムに関して、同脆弱性に関する対応にあたられている方もいらっしゃると思われますが、以下、その作業のお役に立てたら幸いです。

Log4Jを使用しているかではなく、「バージョン番号の確認方法」をお探しの方は、こちら

注意(12/31 追記)

2021年12月31日 日本時間1時現在、Log4J2に関しては、以下の4つの脆弱性が報告され、順次公式から修正版が発表されています。

CVE-2021-44228(最初の脆弱性, 2021/12/10報告)
悪意ある第三者が任意コードの送りつけ実行可能な極めて重篤な脆弱性。v2.15.0で修正。

CVE-2021-45046(2番目の脆弱性, 2021/12/14報告)
一部設定の使用時、v2.15.0の修正が無効という脆弱性。v2.16.0で修正。

CVE-2021-45105(3番目の脆弱性, 2021/12/18報告)
一部設定の使用時、v2.16.0の修正でもDoS攻撃の可能性が残る脆弱性。v2.17.0で修正。

CVE-2021-44832(4番目の脆弱性, 2021/12/28報告)
一部設定の使用時、v2.17.0の修正でもリモートコード実行ができる脆弱性。v2.17.1で修正。

特に重篤で緊急を要する脆弱性はv2.15.0で修正されていますが、2〜4番目の脆弱性も稼動システム現在及び未来にリスクを生じさせる恐れがあるため、v2.15.0やv2.16.0への更新作業を行った皆様も、v2.17.1への更新を行われることをお薦めします。

Log4j 2 インストール手順

緊急・厳重注意 2021年12月10日、Log4J2ライブラリに致命的なセキュリティホールが発見されました(RedHatによる危険度レベルは「10段階中の9.8」であり、世界中で警戒が呼びかけられる事 ...

また、使用しているLog4Jバージョン別に、上記3脆弱性のリスクを検討する材料・目安について、別記事にてまとめましたので、よろしければご利用くださいませ。

【12/31更新】Log4Jの「4つの脆弱性」と使用バージョン別の影響度・緊急度

2021年12月10日に報告されたRCE脆弱性(CVE-2021-44228)をきっかけに、Log4J2ライブラリに対する4つのセキュリティホールが次々と指摘されています。『スッキリわかるJava入門 ...

この記事の対象

この記事で紹介する方法は、自社が開発・運用するシステムで、直接Log4Jを利用しているかを判別するものです。間接的な使用(利用しているライブラリ・フレームワーク・ミドルウェア・その他の製品が内部でLog4Jを利用しているケース)を判別することはできません。それらについては、個別に製造元にご照会ください(※CVE-2021-44228は重大な脆弱性であるため、各社Webサイトに影響が公表されていることも少なくありません)。

利用しているLog4Jのバージョンを確認する方法

第1段階: 仕様書レベル

自社運用システムで「Log4Jが利用されているか」、「どのバージョンを利用しているか」、最も高速で原則的な確認方法は「システム仕様書(設計書)」による確認です。調査精度は落ちますが、エンジニアやオペレーターが不在でも調査を進められるため、「一次回答だけでも迅速に返す必要がある」場合に特に有効です。

システムに関して保管されている最新の仕様書を調べ、その一部として「利用ライブラリ一覧」にLog4Jの使用や使用バージョンが記述されていないかを調べます。仕様書が不存在の場合、または存在しても信用できない場合は、第2段階に進んでください。

ポイント
調査では、仕様書の「更新履歴」や「最終更新日」を確認するとともに、あまりに古い場合や、「その年月日が最終仕様更新であるはずがない」と想像される場合、その仕様書が更新されてない(=信用できない)可能性があります。運用担当部署や担当者に、「仕様書の最終更新のあと、緊急のシステム変更や対応があったか」を確認します1
参考
Log4Jはオープンソース(OSS)のライブラリであることから、大規模商用システムの場合、法務レビューやシステム監査を通過するために「使用OSS一覧」としてきちんと整理がなされてたり、法務部・内部監査室・品質管理部などに記録が残っている可能性があります。

ロガーライブラリは、ログファサード2などを用いていない限り、リリース後に別の製品に切り替えることが困難なため、過去のリリース時や監査時の記録で、Log4Jの使用がうかがわれる記述がある場合、現状でも利用している可能性が極めて高くなります。

なお、今回の脆弱性は、極めてリスクが大きいため、第1段階でLog4Jの利用が検出されなくても、念のため第2段階の調査を行われることをお薦めします。

第2段階: コードベース・納品パッケージレベル

システムのコードベース(gitレポジトリ等)や「納品ファイル一式をzipファイルやDVDで保管してあったもの」を確認し、log4jのJARファイルが含まれているかを確認します。log4jは、多数のJARファイルから構成されますが、log4j-core-2.16.0.jarのような名称のファイルが通常は含まれています。そのため、

「log4j-core」からはじまり、「.jar」で終わる

という条件にヒットするファイルを探すことで、log4jの使用の可能性を検出することができます。また、ファイル名からバージョン番号を判別できます。

Windowsマシンの場合、納品物一式が含まれるディレクトリで、

where /r . log4j-core*.jar

LinuxやMacOSの場合、

find . -name "log4j-core*.jar"

で該当する名前のファイルを探すことができます。

※ヒットしない場合、念のために「log4jからはじまるファイル名」を検索したり、全ファイル横断で「org.apache.log4j」という文字列を検索するのもおすすめです。

注意
gitレポジトリの中身をcloneしてファイルを探す場合、log4jなどの外部依存ライブラリがレポジトリには含まれていない(AntやMavenやgradleを使い、ビルドやデプロイの過程で自動的にダウンロードされて本番機に配備される)可能性があります。この場合、上記のようにして直接ファイルをみつけることができません。

プロジェクトに、build.xml(Antの標準構成ファイル名)、pom.xml(Mavenの標準構成ファイル名)、build.gradlesettings.gradlegradle.properties(Gradleの標準構成ファイル名)が含まれる場合、テキストエディタで開き、その中にlog4jという文字列が含まれていないかを検索します。

なお、何らかの理由で「log4jのjarファイルは見つけられたが、バージョン番号がファイル名から判別つかない」場合は、当記事末尾の方法で調べます。

CI/CDパイプラインでオートデプロイがなされているケースや、運用保守プロセスが厳密に管理されている場合は、この第2段階までで調査を完了することも合理的だと思われます。極めてミッションクリティカルなシステムである場合や、保守要員が本番機に直接sshしてファイルを触るなどのメンテナンスが日常的に行われている場合、念のために第3段階調査に進むことを検討します。

第3段階: 本番機レベル

運用保守用のアカウント等で、正式な運用保守の手続き・承認等を経て、本番機にssh等でアクセスし、log4jのJARファイル(log4j-core〜.jar)が配置されていないか、存在するならばどのバージョンかを確認します。

複数人の担当者が入力コマンドを常にダブルチェックするなど、誤操作による悪影響に十分に注意しながら作業をすすめます。

注意findなど、多数のディレクトリを一気に走査するようなコマンドは、万が一の誤用の時に破壊的な影響や大幅な性能劣化を生じさせる可能性があります。第1段階・第2段階の調査で概ねJARファイルの場所を把握した上で、本番機では単純なcdコマンドとlsコマンドにより、地道な手作業でファイルを探すことをお薦めします。

JARファイル名からバージョン番号が判定できないとき

上述の通り、log4jのバージョンは通常、JARファイルのファイル名の一部として判別できることが一般的です(例: log4j-core-2.16.0.jar)。

しかし、ビルドやデプロイの過程で、log4jのJARファイル名が変更され、バージョン番号が取り除かれることがあります。この場合、ファイル名だけからはLog4Jの使用中バージョンを判定できません。

また、Log4Jは独立したアプリケーションではなく、他のアプリケーションの一部として動くライブラリであるため、「log4j --version」のようなコマンドライン入力で、バージョンを調べることもできません。

そのため、以下のような手順で、JARファイルの中身を分解し、書き込まれたバージョン番号を調べます。

  1. バージョン不明のJARファイル(log4j.jar、とします)を、手元の安全なフォルダにコピーします(本番機上では以下の作業を行わないようにしてください)
  2. ファイル名の拡張子をzipに変更します
  3. zip展開ツール(Windowsの標準ツールでもOK)で、このzipファイルを展開します
  4. META-INFというフォルダがでてくるため、その中のMANIFEST.MFファイルをテキストエディタで開きます
  5. ファイル末尾近くにある「Log4jReleaseVersion: 2.XX.X」という表記を探します

使用しているLog4Jバージョンごとのリスク整理

別記事にまとめました。

その他

  • 今回問題となっているのはLog4Jのバージョン2系です。バージョン1系は実質的に別製品であり、今回の脆弱性の影響を直接受けないと発表があります(ただしサポートを終了しているライブラリなので、使用は推奨されません)
  • 今回の問題は、「2.15.0-rc1」でも発生します。本番システムで、敢えてrc版を利用しているケースは希(rc版を利用するほど急いでバージョンアップをする必要が、ログライブラリの場合は生じづらい)だと思われますが、万が一ご利用の場合はご注意ください。
  • 最も大きな脆弱性(cve-2021-44228)は、「2.15.0」で修正が行われましたが、特定の非デフォルト設定での利用時においては脆弱性が塞がれないことが報告されています(cve-2021-45046, cve-2021-45105, cve-2021-44832)。既に2.15.0や2.16.0へのアップデート対応をなさった方も、「2.17.1」以上にアップデートすることをお薦めします。
  • 別のログライブラリ logback についてもJNDIに関する機能が含まれる指摘(LOGBACK-1591)がなされていますが、実質的には問題ある脆弱性ではありません1
  • (12/20追記) 使用するLog4Jを2.16.0以降に引き上げると、Log4Jに備わる「JNDIルックアップ機能」が無効化されます。この機能を利用しているシステムはかなり希だと想像されますが、正当な理由で使用していた場合、当該機能が動かなくなる点にご注意ください。v2.16.0以降でもシステムプロパティを指定することで有効化できますが、v2.16.0とv2.17.0で指定すべきプロパティ名が異なる点に注意ください。
  • log4j関連のJARファイルは、通常必要があって配備されるものですが、「JARファイルとしては存在するものの、実際には使用していない」ケースもありえます。例えば、フレームワーム「SpringBoot」では、Log4jが含まれますが、デフォルト設定の場合はlogbackで動作するため本脆弱性の影響を受けないとの公式発表があります。その他、過去の経緯でシステムに「Log4JのJARファイルが(既に使っていないが)残存している」ケースもありますが、特に間接利用の場合は実際の使用是非を迅速に解析することが困難なため2、本脆弱性の重篤性を鑑み、Log4JのJARファイルが存在すればまずはリスクありとしたうえで、継続調査しながら順次リスクを否定していくことをお薦めいたします。
  • Log4J2公式サイトで、JARファイルから一部クラスファイルを削除する対応策が紹介されていますが、他社製のライブラリやフレームワークによるLog4Jの間接利用の場合にこの方法を適用するとサポート契約が切れる可能性などがあるため十分ご注意下さい。
  • 利用ライブラリやフレームワークを経由した間接的なLog4Jの利用について、独自に調査が可能なケースも少なくありませんが、ライセンス上、ソフトウェアアーカイブの分解(リバースエンジニアリング)が禁止されていたり、Log4Jライブラリを利用していても見かけ上見つからないケース(独自バイナリファイルやネットワーク上から動的にクラスローディングしているケース、JAR利用ではなくソースコードレベルで取り込まれているケースなど)もあり得るため、利用事実の判定は製造元による公式表明を利用することをお薦めします。
  • 発注者の方・管理者の方へ: 仮に自社システムがLog4J2を利用していたとしても、担当エンジニア・運用員に瑕疵やスキルの不足があったわけではありません。Java業界においてLog4J2は、世界的に有名な実績あるログライブラリとして広く認知されてきた製品であり、優れた技能を持つエンジニアであっても、今回のような脆弱性の発生を予見することは難しく、Log4Jは当然に選ばれることが自然な選択肢の1つでした。

参考記事


Log4j 2 インストール手順

緊急・厳重注意 2021年12月10日、Log4J2ライブラリに致命的なセキュリティホールが発見されました(RedHatによる危険度レベルは「10段階中の9.8」であり、世界中で警戒が呼びかけられる事 ...

「RCE(リモートコード実行)」を行うdokojavaやdokoC等で、今回のLog4Jのような問題が生じない理由の説明

-お知らせ, loggers