日本語│English
       

株式会社アイオーアーキテクトは、オープンソースなどを活用してシステム運用を最適にご提供します。

  • ホーム
  • OTRS
  • サービス内容
  • 会社案内
  • ラボノート
  • お問い合わせ
  1. HOME
  2. ラボノート
  3. Log4j JndiLookupを抜いたときの挙動

ラボノート

2021/12/16 平見知久
Tweet
Log4j JndiLookupを抜いたときの挙動

ここのところホットなLog4jで見つかった脆弱性ですが、Log4j バージョン2.10より前のときの対策で、「JndiLookupクラスをクラスパスから削除する」というのを見て、ぱっと直感的に「抜いて大丈夫なのかな?なんか変な挙動起こさないかな?」と疑問に思ったので軽くソースを覗いてみました。

ちなみにOTRS, OTOBOはperlとJavascriptで書かれたアプリですのでLog4J(というかJava)の脆弱性の影響は受けません。ただ、OTOBOでは検索の高速化の機能のためにElasticsearchと連携できるようになっています。ElasticsearchはJavaでLog4jも使用していますので影響を受けることになります。また、OTRSでも弊社独自で用意したElasticsearch連携のアドオンが存在しており、その関連で気になった次第です。

お断り: 軽くソースを覗いた内容ですので、その真正性はあくまでご自身でご判断ください。本記事を信じて行ったこと/行わなかったことに対するいかなる責任も負いませせん。テストは大事です。

ソースは諸々の事情から、Log4j 2.8.2を使っています。

展開してgrepすると、問題のJndiLookupはlog4j-core.jarの、org/apache/logging/log4j/core/lookup/JndiLookup.javaが該当します。同列のlookupディレクトリを見ると、AbstractLookupを筆頭にDateLookupとか、EnvironmentLookup, JavaLookup等と並んでいますので、おそらくAbstractLookupを基底クラスにしたプラグインっぽい実装になっていそうです。

JndiLookup.javaを見てみると、クラスの出だしが次の通り。

@Plugin(name = "jndi", category = StrLookup.CATEGORY)
public class JndiLookup extends AbstractLookup {

やっぱりAbstractLookupを基底にして、まんまPluginというアノテーションついていますので、扱い的にはプラグイン、と。

そうするとどこからロードしているかが気になりますのでソースに対してgrepかけてみると、テストコードやドキュメント類を除くとorg/apache/logging/log4j/core/lookup/Interpolator.javaがクラスを呼んでいます。

public Interpolator(final Map<String, String> properties) {
  this.defaultLookup = new MapLookup(properties == null ? new HashMap<String, String>() : properties);
  // TODO: this ought to use the PluginManager
  lookups.put("log4j", new Log4jLookup());
  lookups.put("sys", new SystemPropertiesLookup());
  lookups.put("env", new EnvironmentLookup());
  lookups.put("main", MainMapLookup.MAIN_SINGLETON);
  lookups.put("marker", new MarkerLookup());
  lookups.put("java", new JavaLookup());
  // JNDI
  try {
    // [LOG4J2-703] We might be on Android
    lookups.put(LOOKUP_KEY_JNDI,
    Loader.newCheckedInstanceOf("org.apache.logging.log4j.core.lookup.JndiLookup", StrLookup.class));
  } catch (final LinkageError | Exception e) {
    handleError(LOOKUP_KEY_JNDI, e);
  }
  // JMX input args

他のLookupプラグインはともかく、JndiLookupについてはエラーハンドリングされていて、クラスが読めなかったらhandleErrorで処理しているみたいです。JavaLooupクラス等を抜いてしまうとロード時にエラーで落ちますが、このコードの書き方はない場合にはないなりに動かそうという書き方です。

handleErrorはというと、特に落ちたりせずに警告ログだけ出して終わっています。

private void handleError(final String lookupKey, final Throwable t) {
  switch (lookupKey) {
  case LOOKUP_KEY_JNDI:
    // java.lang.VerifyError: org/apache/logging/log4j/core/lookup/JndiLookup
    LOGGER.warn( // LOG4J2-1582 don't print the whole stack trace (it is just a warning...)
      "JNDI lookup class is not available because this JRE does not support JNDI." +
      " JNDI string lookups will not be available, continuing configuration. Ignoring " + t);
    break;

ちなみに、大本のInterpolatorについてはどこから呼ばれてるかというと、何か所かありますが、org/apache/logging/log4j/core/config/AbstractConfiguration.java あたりでクラスのメンバ変数の初期化でばっちり呼ばれています。

private final StrLookup tempLookup = new Interpolator(properties);

AbstractConfigurationの名の通り、Log4Jの設定の基底クラスですから、ライブラリの初期化さえ通ってしまえばまずまず問題はなさそうです。

まとめると

  • 問題を起こしているJndiLookupクラスについてはプラグインの1種として扱われている(=必須機能として扱われていない)
  • もともと存在しない場合でも大丈夫なようなコードになっている
  • ライブラリの初期化さえ通ってしまえば後で問題になる可能性は低い

ということで、提示されている対処通り、「JndiLookupクラスをクラスパスから削除する」という対処で問題なさそうということで個人的には納得です。

ちなみに、クラスパスを削除するといってもJndiLookup.classはlog4j-core.jarの中に入っていますので、実質jarから該当クラスを抜くという操作になります。

いくつか思いついたり探したりした中ではjarは実質zipファイルですので、

# zip -d log4j-core-2.8.2.jar org/apache/logging/log4j/core/lookup/JndiLookup.class
 
あたりが楽でしょうか。jarを直接書き換えますので操作前の元ファイルの保全と変更後の動作確認はお忘れなく。
 
OTRS、OTOBO、Zunuyとしての対策は、保守サポートのFAQに掲載しておりますので、こちらをご参照下さい。
  • OTOBO(OTRS)
  • 事業内容
  • 会社案内
  • お問い合わせ
  • ラボノート
  • カテゴリ
    • CMDBuild (1)
    • OCS Inventory NG (3)
    • OpenAudIT (8)
    • OSS (8)
    • OTOBO (61)
    • OTRS (96)
    • SnipeIT (1)
    • Znuny (20)
    • オープンソース (18)
    • 未分類 (1)
    • 豆知識 (7)
    アーカイブ
    • 2025年4月 (1)
    • 2025年3月 (4)
    • 2025年2月 (1)
    • 2024年11月 (1)
    • 2024年10月 (5)
    • 2024年9月 (4)
    • 2024年8月 (4)
    • 2024年7月 (5)
    • 2023年12月 (5)
    • 2023年8月 (2)
    • 2022年6月 (2)
    • 2022年5月 (1)
    • 2022年4月 (1)
    • 2022年3月 (2)
    • 2022年2月 (1)
    • 2022年1月 (6)
    • 2021年12月 (16)
    • 2021年11月 (4)
    • 2021年8月 (1)
    • 2021年4月 (1)
    • 2021年3月 (2)
    • 2021年2月 (2)
    • 2021年1月 (2)
    • 2020年5月 (1)
    • 2019年10月 (1)
    • 2019年8月 (1)
    • 2019年6月 (1)
    • 2019年2月 (2)
    • 2018年12月 (1)
    • 2018年10月 (3)
    • 2018年9月 (2)
    • 2018年8月 (1)
    • 2018年7月 (5)
    • 2018年6月 (3)
    • 2017年12月 (3)
    • 2017年11月 (4)
    • 2017年10月 (1)
    • 2017年9月 (2)
    • 2017年8月 (2)
    • 2017年7月 (1)
    • 2017年5月 (2)
    • 2017年4月 (4)
    • 2017年3月 (1)
    • 2017年2月 (3)
    • 2017年1月 (2)
    • 2016年12月 (2)
    • 2016年11月 (4)
    • 2016年10月 (3)
    • 2016年8月 (3)
    • 2016年7月 (1)
    • 2016年6月 (2)
    • 2016年5月 (4)
    • 2016年4月 (2)
    • 2016年3月 (1)
    • 2016年2月 (1)
    • 2016年1月 (2)
    • 2015年12月 (1)
    • 2015年8月 (1)
    • 2015年6月 (1)
    • 2015年5月 (3)
    • 2015年4月 (3)
    • 2015年3月 (3)
    • 2015年2月 (3)
    • 2015年1月 (3)
    • 2014年12月 (4)
    • 2014年11月 (4)
    • 2014年10月 (4)
    • 2014年9月 (2)
    • 2014年8月 (1)
Tweet

〒279-0004 千葉県浦安市猫実1-20-43
MAIL sales@io-architect.com

       
HOME OTOBO,Znuny,OTRS 事業内容 会社案内 ラボノート
保守サポート チケット管理サポート 会社概要 お問い合わせ
いつくしまパッケージ OpenAuditサポート 企業理念  
CRM機能(ContractDB) DRBDサポート プライバシーポリシー  
CTI連携(BIZTEL CTI) Kompiraサポート    
IT資産管理(CMDBReadyToUse) OSS導入サポート    
 導入事例 OSS導入事例    
 リリース情報 その他の技術支援    
© IO Architect Inc. 2016 - 2024
pagetop