お知らせ loggers

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

2021年12月10日に報告されたRCE脆弱性(CVE-2021-44228)をきっかけに、Log4J2ライブラリに対する4つのセキュリティホールが次々と指摘されています。『スッキリわかるJava入門』で学ばれエンジニアとしてご活躍中の方の中には、自身が運用中のシステムに関して、同脆弱性に関する対応にあたられている方もいらっしゃると思われます。

可能ならば、最新版(v2.17.1)に利用バージョンを引き上げるのが理想ではありますが、「つい先日に緊急対応したばかりなのに、再度の緊急対応が必要なのか」等、対処や判断、お客様への説明に悩まれることもあるかもしれません。以下の内容がお役に立てば幸いです。

前提: 報告されている4つの脆弱性

2021年12月31日 日本時間午前1時現在、Log4J2に関して報告されている4つの脆弱性は以下の通りです。

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

CVE-2021-45046(2番目の脆弱性, 2021/12/14報告, CVSSスコア=9.01)
一部設定の使用時、プログラムの処理内容によっては、v2.15.0使用時でも悪意ある第三者が任意コードの送りつけ実行可能という脆弱性。v2.16.0で修正。

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

CVE-2021-44832(4番目の脆弱性, 2021/12/28報告, CVSSスコア=6.6)
一部設定の使用時、v2.17.0使用時でもDoS攻撃の可能性が残る脆弱性。v2.17.1で修正。

前提: 現在の使用バージョンの確認

現在、自分のシステムがLog4Jを利用しているか、利用しているとしたらバージョンがいくつであるかが不明な場合、以下の記事を参考にバージョン特定を行います。

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

Log4J2に関するRCE脆弱性(CVE-2021-44228)が世界的な問題となっています。『スッキリわかるJava入門』で学ばれエンジニアとしてご活躍中の方の中には、自身が運用中のシステムに関して ...

現在利用中のバージョンが v1.XX.Xの場合

バージョン1系のLog4Jは、今回の4つの脆弱性(44228, 45046, 45105, 44832)の影響を直接受けません1

ただし、バージョン1系は既に開発やサポートが終了しているため、将来、今回のような重篤な脆弱性が発見された場合に対応が行われない(行われづらい)リスクを抱えており、なるべく早い更改が望まれます。たとえ自分が担当から外れたあとでも、次回の保守やシステム更改の検討時に漏れなくロガーライブラリの改訂が盛り込まれることになるよう、運用保守に関する記録(公式な運用保守文書、リスク管理表、チケットシステム等)に記録を残します。

現在利用中のバージョンが v2.0.0〜v2.14.Xの場合

最も重篤な、最初の脆弱性(CVE-2021-44228)の影響を直接受けるバージョンを利用しています。

この脆弱性は、悪意ある第三者が容易な方法で「サーバーへの侵入・改ざん・乗っ取り」を行えてしまう可能性があり、既に世界中で広く攻撃が確認されているため、1秒でも早い対応が望まれる応急性のものです(「あわてて緊急対応をせず、様子を見る」という判断が合理的バランス点となるシステムは、ほぼ存在しないと想像されます)。

推奨 可及的速やかに、v2.17.0以降にバージョンを引き上げてください。(Java7以前環境では、v2.12.2)

Log4j 2 インストール手順

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

注意なお、最初の脆弱性(CVE-2021-44228)への対応方法として過去にLog4J公式から紹介があった「log4j2.formatMsgNoLookupsシステムプロパティやLOG4J_FORMAT_MSG_NO_LOOKUPS環境変数を用いた対処方法」は、後述の「2番目の脆弱性」に対する対応としては機能しないため、現状では採用するメリットがありません(Log4J公式でも、対処方法として取り下げられています)。

参考当分バージョンを引き上げられない事情がある一方、利用者の安全を考慮して「一時的なサービス停止」が許容されるシステムでは、稼動を停止させることも検討してください。当脆弱性を抱えたまま稼動を継続するサーバー(特にWebシステム)は、配信するコンテンツが改ざんされ、システム利用者にウィルスやスパイウェアを侵入させるなどのために悪用される恐れがあり、二次被害が広がる危険性があるためです。

既に脆弱性の表出化から10日間が経過しているため、中央省庁、地方自治体、軍事・防衛関連、社会インフラ関連、大企業のシステムに対しては、CVE-2021-44228を利用した攻撃が実施されている可能性も十分想定されます。万が一、まだ対処が完了していない場合、急ぎ応急対処で脆弱性を塞ぎ、侵入形跡の調査に進む必要性の検討を行われることをお薦めします。

今回の脆弱性は、外部からの侵入を許す類のものであるため、「攻撃者は、侵入と同時に、サーバーログを改ざんして自分の侵入記録を消す」ことが論理上可能です。さらにアプリケーションサーバーの稼働ユーザーが特権を持っていた場合、運用保守メンバーのログインシェルやsu/sudoに細工がなされ、偽装やさらなる攻撃に利用される恐れもあります。一般的なITエンジニアの手で、安全かつ適切な侵入形跡調査を行うことは容易ではないと想像されるため、特に政府機関や社会的に重要なITシステムに関する侵入形跡調査では、専門家の支援を得ることお薦めします。

現在利用中のバージョンが v2.15.0-rcXの場合

v2.15.0-rc1などは、正式なv2.15.0が発表される「直前」のバージョンです1。よって、このバージョンのLog4Jは、v2.15.0でなされた脆弱性対処がまだ行われていません。

上記の「v2.0.0〜v2.14.X」と同じ緊急度で、対応を行う必要があります。

現在利用中のバージョンが v2.15.0の場合

v2.15.0を利用している場合、最も致命的な「最初の脆弱性」の影響は受けませんが、「2つ目・3つ目・4つ目の脆弱性を用いた攻撃を受ける可能性」が残っています。

ただし、2つ目の脆弱性(cve-2021-45046)は、最初の脆弱性ほど簡単に悪意ある第三者が攻撃を成功させられるわけではなく、

  • Log4Jの設定で「ログ出力の形式」をカスタマイズ指定している場合、かつ、
  • ContextLookupという機構で、TheadContextMap2内の値を取り出して利用している場合、かつ、
  • 利用しているTheadContextMapのキー名等を攻撃者に推測され、そのキーに対応する値として、システム外部からの値の格納を許した場合

に、最初の脆弱性(cve-2021-44228)同様の侵入・リモートコード実行リスクが生じる恐れがあるとのことです。

そのため、「自社システムのLog4Jの設定で、ContextLookupを利用しているか」を確認することが重要になります。この確認(及び後述するThreadContextMapの利用状況の確認)は、多くの場合、机上(システム仕様書)で行うことが難しく、納品コード一式またはソースコードレポジトリ内のファイルを用いる必要が生じると思われます。

推奨 下記の「ContextLookupの使用確認」の調査やその後の検討にかかる工数と、「Log4Jライブラリを最新バージョンまで引き上げる」工数を比較します。もし状況的に、Log4Jライブラリの更新が容易ならば、以下の確認を行う必要はなく、Log4Jを最新版に更新することで当脆弱性のリスクに対応できます。

ContextLookupの使用確認


納品コード(またはgitレポジトリ内のコード)のファイル一式を取得し、全てのXMLファイル(.xml)、JSONファイル(.json)、YAMLファイル(.yaml または .yml)、プロパティファイル(.properties)及びJavaソースファイル(.java)を対象にして、以下の文字列が含まれる部分が存在するかを、ファイル横断で検索します。

  • ${ctx:
  • %X
  • %MDC
  • %mdc

検索の結果、「Log4Jの出力フォーマット指定として、上記記述が含まれている」と見受けられる場合、ContextLookupを利用してThreadContextMapへアクセスしている可能性が高くなります。

例1: %d %p %c{1.} [%t] $${ctx:loginId} %m%n
例2: %d [%t] %-5p %X{requestId, sessionId, loginId, userId, ipAddress} %C{1.}.%M:%L - %m%n

注意 Log4Jでは、設定ファイル(xmlファイル等)だけではなく、Javaソースファイル内でも、メッセージフォーマットの指定・設定が可能です。そのため、設定ファイルだけを対象に上記調査を行うと漏れが生じる可能性がある点にご注意ください。

参考 %Xという文字列は、Stringクラスのformat()メソッドやprintf()メソッドなどで16進数を出力するために利用されることがあります。また、Log4J構成ファイルに含まれていたとしても、コメントアウトされていたり、そのロガーが実際には使われていない可能性もあります。そのため、検索で%Xが発見されたからといって、すぐに当脆弱性の影響を受けるとは断定できない点に注意してください。

もし、ContextLookupを利用している場合であっても、システムが外部から受け取る入力データを、ログ形式パターンのキー名(上記例1の場合のloginId)に対応する値として、ThreadContextMapに格納しないならば(または格納値が英数字のみか検証するなどして、悪意ある文字列の格納を排除している場合)、当脆弱性に基づく攻撃は成立しません。

ただし、上記調査にはそれなりに工数がかかる一方、万が一漏れがあった場合等にリモートコード実行を行える致命的な危険性が残るため、原則としては速やかなLog4Jライブラリのバージョンアップ(v2.17.0以降。Java7以前はv2.12.2)をお薦めします。

何らかの事情でライブラリの更新が難しい場合で、かつ、「当該リスクが存在しない、または、十分小さく受容可能」と合理的に判断できる場合のみ、次回なるべく早い保守タイミングでLog4Jライブラリの更新が行われるよう保守記録やチケットシステムに記録します。

現在利用中のバージョンが v2.16.0の場合

v2.16.0を利用している場合、「最初の脆弱性」「2つめの脆弱性」の影響は受けませんが、「3つ目と4つ目の脆弱性の影響を受ける可能性」が残っています。

3つめの脆弱性も、2つめの脆弱性同様、「ContextLookup」を利用して、ThreadContextMapにアクセスする場合のみ、問題となります。ただし、「%x」や「%MDC」のような%からはじまる記述の場合には問題とはならず、「${ctx:」のように$から始まる記述の場合にのみ問題が生じます3

また、2つめの脆弱性とは異なり、サーバーに侵入されたり乗っ取られたりするわけではなく、悪意ある第三者がサーバーに負荷をかけてサービスを止めることができてしまう(DoS)というものです。

そのため、「規模や重要度を鑑みて、攻撃者がサービス停止を狙う価値が明らかに低いサービス」や「一時的にサービスが止まっても、大した問題にはならないサービス」では、そのリスクを許容して、緊急対応ではなく次回の通常保守タイミングまで対応を遅らせることも、合理的な判断としてありうるでしょう4

もちろん、速やかなLog4Jライブラリのバージョン引き上げが可能ならば、それに超したことはありません。

参考
社会的影響があるシステムの場合、すぐにDoS攻撃による悪影響がでなかったとしても、安心して対処を後回しにするのは危険です。DoSを行う攻撃者としては、まずは対象システムが「DoSが可能か」だけを検証した上で本格的な攻撃は行わず、後日、システム停止による影響が最も大きくなる時期(有事・重要イベント時など)のタイミングを狙って本格的な攻撃を行うことが、最も有効なためです。

現在利用中のバージョンが v2.17.0の場合

Log4J v2.17.0を利用している場合、1〜3番目の脆弱性の影響は受けませんが、2021/12/28に広く認知された(初回報告は12/11)4つ目の脆弱性の影響を受ける恐れがあります。

4つ目の脆弱性は、1つ目・2つ目と同じく「リモートコード実行」の脆弱性であるため、もし攻撃が成立してしまった場合は、3番目の脆弱性よりシビアな侵害に繋がります。しかし、この攻撃が成立するためには、攻撃者は「Log4Jの設定ファイルを外部から書き換えられる必要がある」とのことで、一般的なシステムではこの条件が成立することは希でしょう5

そのためか、脆弱性の深刻度指標であるCVSSでも、この4番目についてはやや低め(6.6)に設定されているようです(1番目=10.0, 2番目=9.0, 3番目=7.5)。社会的に重要システムでは、念のため「ログ構成の外部書き換え機構を有するか」を確認しておくことができると安心ですが、当該設計のリスクは「1〜3番目の脆弱性への対応」の段階においても認識・報告されうる内容であることから、この12月に特段懸念があがらなければ、1番目や2番目の脆弱性のような緊急対応を要するものではないと推定するのも合理的でしょう。

何らかの理由でログ構成を信用できない第三者に許していることが明らかなケースでは、2.17.1(Java6では2.3.2, Java7では2.12.4)への引き上げを検討すると共に、本件以外にも致命的なリスクにつながりかねない「ログ構成を不特定の第三者に許す設計」についていまいちど、代替案が考えられないか再検討されることを推奨します。

現在利用中のバージョンが v2.17.1以降の場合

Log4J v2.17.1以降を利用している場合、現状報告されている4つの脆弱性の影響は受けないとされています。
今後も異なる脆弱性が報告される可能性があるため、引き続き最新情報を定期的に確認してください。

Log4J公式 https://logging.apache.org/log4j/2.x/security.html

注意以下の内容は2021年12月31日 1時00分(日本時間)時点のものです。状況は常に変化するため、併せて最新情報も独自に調査の上、ご活用ください。

Log4J2 公式セキュリティ情報 https://logging.apache.org/log4j/2.x/security.html

関連記事

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

Log4J2に関するRCE脆弱性(CVE-2021-44228)が世界的な問題となっています。『スッキリわかるJava入門』で学ばれエンジニアとしてご活躍中の方の中には、自身が運用中のシステムに関して ...

-お知らせ, loggers