This post is also available in: English (英語)

概要

パロアルトネットワークスのリサーチャーは GitHub で 81,000 個以上のスターを獲得している人気オープンソース生成 AI フレームワーク LangChain における 2 つの脆弱性を特定しました。

LangChain の Web サイトでは、は「100 万人以上の開発者が LLM アプリの開発に LangChain フレームワークを使っている」と述べられています。LangChain のパートナー パッケージには、クラウド、AI、データベースなどの技術開発大手企業が多数含まれています。

これら 2 つの脆弱性はそれぞれ、攻撃者に任意のコード実行を許可するものと、機微データへのアクセスを許可するものでした。LangChain はその後、これらの脆弱性を解決するパッチをリリースしています。本稿は、これらの脆弱性をめぐり技術的に検討すべき点を包括的に提供し、将来同様の脅威を緩和するためのガイダンスを提供します。

これらの脆弱性が確実に修正されるよう、パロアルトネットワークスでは LangChain ユーザーには製品の最新バージョンをダウンロードすることを推奨しています。

パロアルトネットワークス製品をお使いのお客様は CVE-2023-46229 と CVE-2023-44467 を使った攻撃からより適切に保護されます。

関連する Unit 42 のトピック 脆弱性

技術分析

LangChain の概要

LangChain は、大規模言語モデル (Large Language Model: LLM) の利用を簡素化するためのオープンソース ライブラリーです。同ライブラリーは組み立てて使える構成ブロックを多数提供していて、たとえばモデルへのコネクターやサードパーティ サービス統合、LLM で使えるツール インターフェースなどが提供されています。

ユーザーはこれらのブロックをつないでチェーンを作れます。これにより、検索拡張生成 (RAG) などの機能を使って LLM を拡張することができます。RAG は、プライベートな内部文書、最新ニュースやブログなどの大規模言語モデルに追加の知識を提供できる技術です。

アプリケーション開発者はこれらのコンポーネントを使って高度な LLM 機能を自分たちのアプリに統合できます。開発者が基本的な大規模言語モデルを LangChain に接続する前は、トレーニング中、そのモデルはその時点で利用可能なデータに依存していました。LangChain への接続を確立して RAG を統合した後は、そのモデルは最新データにアクセスできるようになり、最新情報で回答を提供できるようになりました。

LangChain はコミュニティで大きな人気を博しています。2024 年 5 月現在、コア リポジトリーには 81,900 を超えるスターと 2,550 人を超える貢献者がいます。LangChain はリポジトリー内で多数の構築済みチェーンを提供しており、その多くはコミュニティによって貢献されたものです。開発者はこれらのチェーンをアプリケーションで直接使用できるので、独自の LLM プロンプトを構築してテストする必要性が緩和されます。

パロアルトネットワークスのリサーチャーは、LangChain と LangChain Experimental に脆弱性があることを特定しました。ここではこれらの脆弱性の包括的分析を提供します。

CVE-2023-46229

0.0.317 より前のバージョンの LangChain は、細工されたサイトマップによるサーバーサイド リクエスト フォージェリ (SSRF) に対して脆弱です。攻撃者にこの脆弱性を悪用された場合、アクセス制御が回避され、イントラネットから機微情報を取得される可能性があります。この脆弱性は CVE-2023-46229 として追跡されています。

パロアルトネットワークスの調査により 2023 年 10 月 13 日にこの脆弱性が発見され、LangChain のサポートにただちに通知されました。LangChain はプル リクエスト langchain#11925 でこの脆弱性を修正し、バージョン 0.0.317 でリリースしました。

CVE-2023-46229 の技術的詳細

LangChain は、サードパーティの Web サイトからドキュメントを読み込む機能を提供しています。公開された Web サイトからコンテキストを学習するこの機能は、ユーザーにとって非常に価値の高い機能です。この機能は RAG の実装の 1 つで、これを使えばユーザーがモデルにドキュメントを手動で提供する通信プロセスの処理が楽になります。さらに、サイトマップ URL を受け入れて、そのサイトマップに記載されている URL にアクセスさせる LangChain の機能により、そのパワーと実用性がさらに強化されています。

LangChain のサイトマップについての公式文書は、SitemapLoader が指定された URL のサイトマップに記録された全ページから情報をスクレイピングし、各ページのドキュメントを出力する方法について解説しています。

SitemapLoader 機能により、LangChain と統合された LLM は次のような機能を使えるようになります。

  • サイトマップの Web ページへのアクセスと解析
  • これらの Web ページに含まれるリンクの抽出
  • これらの Web ページから抽出されたリンクへのアクセス

ただし、当初の LangChain はサイトマップのアクセス範囲に制限を設けていなかったため、SSRF の脆弱性につながる可能性があります。

SitemapLoader クラスは langchain/libs/langchain/langchain/document_loaders/sitemap.py というファイル内で定義されている WebBaseLoader クラスの拡張クラスです。 WebBaseLoader クラスは langchain/document_loaders/web_base.py 内で定義されていて、クラス コンストラクターとして web_path を受け取ることができます。基底クラスの WebBaseLoader はまた、 web_path が文字列かどうかもチェックします。

WebBaseLoader は、Web ページを読み込むときに urllib (URL 操作用メソッドを提供する Python モジュール) を使い、HTML を解析するときに BeautifulSoup (HTML 解析用メソッドを提供する Python モジュール) を使います。SitemapLoader WebBaseLoader を継承しているので、URL (web_path) を入力として受け取り、その URL 内のコンテンツをサイトマップとして解析します。 SitemapLoader はサイトマップ内の各 URL にアクセスし、そのコンテンツを取得します。

SitemapLoader クラスは load メソッドを持っています。このメソッドは web_path がサイトマップとして指定した XML ファイルを解釈します。その後は parse_sitemap メソッドを使ってサイトマップからすべての URL を解析・抽出します。その後、scrape_all メソッドが _fetch メソッドを直接呼び出して aiohttp.ClientSession.get を使います。このさい、フィルタリングやサニタイズは何も行われません。

脅威アクターは、提供されるサイトマップ内にイントラネット リソースへの URL を含める可能性がありました。これにより、リストされた URL からのコンテンツが取得されて返されたときに SSRF が発生し、機微データが意図せず漏えいする可能性があります。

組織のイントラネットには、機微情報を返す可能性があることを理由として、公開インターネットからのアクセスを想定していない HTTP API が存在している場合があります。脆弱なバージョンでは、攻撃者が脆弱性を利用してこの種の API にアクセスして機微情報を盗み出したり、API の設計が不適切な場合は、リモート コード実行を実行できます。

ネットワーク トラフィック フロー

結果

図 1 は、ある仮想のシナリオでの攻撃を表す図です。ここではある攻撃者が sensitive.html へのアクセスに成功し、機微情報を入手したものとしています。

攻撃者が悪意のあるコマンドを使って、パブリック サーバーおよびイントラネット サーバーを介して内部サーバーの機微データにアクセスするというサイバーセキュリティ脅威シナリオを示した図。この図には、データとコマンドの流れを示すラベル付きのブロックと矢印が含まれています。右下隅には、Palo Alto Networks と UNIT 42 のロゴが表示されています。
図 1. CVE-2023-46229 の攻撃シーケンス図

この例で sensitive.html は極秘とみなされ、その情報は従業員のみが閲覧できる必要があります。たとえばこれは社会保障番号 (SSN) や従業員の自宅住所など実際の機微情報に相当すると考えればよいでしょう。さらにこのシナリオでは、攻撃者は組織内の API アクセスを侵害し、その API 機能を利用して悪意のあるコマンドを実行しました。

図 2 に示すように、CVE-2024-46229 の SSRF 攻撃が成功すると、組織内での不正アクティビティやデータ アクセスにつながる可能性があります。場合によってはこの SSRF が API 設計に問題のあるアプリケーションやそうしたアプリケーションと対話する別のバックエンド システムで発生し、攻撃者に任意のコマンドの実行を許してしまいかねません。

コンピューター画面でオープンになったターミナル ウィンドウが表示されています。ターミナル ウィンドウには、ソース コードの行と API からの応答データが表示されています。
図 2. CVE-2023-46229 のエクスプロイト結果

CVE-2023-46229 の緩和策

この脆弱性の緩和のため、LangChain は _extract_scheme_and_domain という関数と、許可されたドメインをユーザーが制御できる許可リスト (allowlist) を追加しました。

CVE-2023-44467

CVE-2023-44467 は LangChain Experimental の 0.0.306 より前のバージョンにおいて特定された、緊急 (critical) のプロンプト インジェクションの脆弱性です。LangChain Experimental は研究および実験目的の関数を含む、別個の Python ライブラリーです。このライブラリーには、悪意のあるプロンプトが入力された場合に悪用されうる統合が複数含まれています。

この脆弱性は PALChain 呼ばれる機能に影響します。PALChain はコード ソリューションの生成能力によって言語モデルを強化するよう設計されている機能で、その実現にプログラム支援言語モデル (PAL) と呼ばれる技術が使われています。この脆弱性があることで、PALChain の処理能力をプロンプト インジェクションによって攻撃者に悪用され、システムによる実行が意図されていないような有害なコマンドやコードが実行されてしまうおそれがあります。これにより、不正アクセスや改ざんなど、重大なセキュリティ リスクにつながる可能性があります。

パロアルトネットワークスのリサーチャーがこの脆弱性を発見し、2023 年 9 月 1 日に LangChain の開発チームに連絡しました。その翌日、LangChain チームは LangChain Experimental の pypi ページ上で警告を発しました。

CVE-2023-44467 の技術的詳細

PALChain は langchain_experimental パッケージに含まれる Python クラスの 1 つで、ユーザーのクエリーを実行可能な Python コードに変換する機能を提供しています。LangChain は、langchain/libs/experimental/langchain_experimental/pal_chain/base.py 内で定義されている from_math_prompt() メソッド内で、その例を 1 つ提供しています。

ユーザーは自然言語で数学的なクエリーを入力できます。すると PALChain が API 呼び出し経由で LLM にアクセスし、その数学的なクエリーを Python コードに変換するよう指示します。得られたコードは直接評価され、ソリューションが生成されます。

この機能は、AI を活用して実用的な計算タスクを解決しようとしている人にとって強力なツールとなります。ただし、このアプローチには、プロンプト インジェクション攻撃に対する脆弱性など、一定のリスクが伴います。安全なプログラミングの基礎は、ユーザー入力の厳格な検証またはサニタイズです。

プロンプト インジェクション

プロンプト インジェクションとは、与えられた指示 (「プロンプト」とも呼ばれる) を操作して AI を騙し、意図しないアクションを AI に実行させることと同様のものです。この技術では、AI のコマンド処理システムの脆弱性を悪用し、有害なコマンドを実行したり、制限されたデータにアクセスしたりします。

LangChain ライブラリーのテスト用スクリプトから抽出した PALChain のユーザー入力例は次のようなものです。

ここで PALChain が LLM に Python ソリューションを生成するよう指示します。

ユーザー入力に図 3 に示したようなコマンドが含まれている場合、LLM には上記の例のようなソリューション コードの生成が要求されません。代わりに、LangChain を実行しているサーバーは、ユーザーの要求に応じて指定されたアクションを実行します。

図 3. 悪意のあるユーザー入力

この悪意のあるコードはどのようなものでもかまいません。上の図 3 では、ls コマンドを例として示しています。LLM は、図 4 に示したような応答内で、悪意のあるコードを返す可能性があります。

Python コードを表示するコーディング ターミナルのスクリーンショット。このコードは 'os' モジュールをインポートし、Linux の 'ls' コマンドを実行してディレクトリーの内容を一覧表示します。ターミナル ウィンドウにはダーク テーマが設定されていて、黒い背景と白いテキストが表示されています。ウィンドウの左上隅には macOS の 3 色のボタン (左から赤の閉じるボタン、黄のしまうボタン、緑の画面サイズ変更 ボタン) があります。
図 4. Python インタープリターが実行するコード

このコードを実行すると、組み込みモジュールの os がインポートされ、system() 関数を呼び出してシステム コマンドの ls を実行します。

一般に、正当な質問とプロンプト インジェクション攻撃を区別することは困難です。そこで PALChain は生成されたコードが Python インタープリターで評価される前に、コードの検証を実施しようとします。

サニタイズのバイパス

PALChain クラスの from_math_prompt() メソッド内部では、LangChain Experimental の採用するセキュリティ メカニズムに 2 つのフラグが設定されています。

  • allow_imports
  • allow_command_exec

これらのフラグはそれぞれ、「パッケージのインポートが許可されるか」、「コマンド実行機能が許可されるか」を制御します。図 5 にこれらのチェックを示します。

  • allow_imports False に設定されている場合は検証で import 文がチェックされ、見つかった場合は例外を発生させます。
  • allow_command_execFalse に設定されている場合は検証でコードが危険とみなされる関数を呼び出しているかどうかがチェックされます。
    • 検証コードには危険な関数のブロックリストが含まれています。
    • コードが送信されると、コードは構文ツリーへとパースされ、そのノードがイテレートされて関数呼び出しが識別されます。
    • いずれかの関数がブロックリストのエントリーに一致すれば、ValueError がトリガーされます。
ダークテーマの黒い背景の上に、赤、緑、白などのテキストがコードを表示している、コンピューター プログラミング インターフェイスのスクリーンショット。このコードにはさまざまな要素が含まれています。たとえば、関数定義、条件文、コマンド実行やインスタンス ノードの機能に関連する問題を示すエラー メッセージなどです。
図 5. CVE-2023-44467 の脆弱なコード

バージョン 0.3.5 までは、LangChain のブロックリストには systemexecexecfileeval の 4 つの関数が含まれていました。LangChain では、とくに import 文とコマンド実行の両方が制限されている場合、これらの関数だけで危険な関数の実行リスクの緩和できると判断されていました。

例を以下にあげます。

  • system: os.system() を防止する。これの実行には import os も必要だが allow_importsFalse に設定されていれば import os は禁止される。
  • exec: exec() 関数をブロックする。この exec() 関数は、任意の文字列をコードとして評価できる関数。
  • execfile: execfile("malicious.py") といった文の使用を禁止し、指定ファイル内の任意のコードの実行を防ぐ。
  • eval: eval() 関数をブロックする。eval() 関数は任意の文字列をコードとして評価できる関数。

このアプローチでは、import 文を禁止し、特定の組み込みコマンド実行関数をブロックすることで、理論上、許可されないコードや有害コードの実行リスクが緩和されます。ただしこうした制限の実装は難しく、とくにバイパス技術がたくさんあるPython のように高度に動的な言語ではそれが顕著です。

これらのバイパスの著名な例は、組み込み __import__() 関数の利用で、この関数はモジュール名の文字列をパラメーターに指定してモジュールをインポートすることができます。この方法で、抽象構文木 (AST) を回避し、import 文のサニタイズを回避し、subprocess のようなモジュールをインポートできるようになります。以下の概念実証 (図 6 と 7) は、subprocess モ ジュールを使ったリモート コード実行を表しています。

PoC (概念実証)

Python コードを表示するコンピューター コード エディターのスクリーンショット。コードは、LangChain と OpenAI からパッケージをインポートしていて、計算タスク用のプレースホルダーを含んでいます。
図 6. CVE-2023-44467 の概念実証コード
ダーク テーマを使った黒い背景に、コマンド ライン インターフェイスを表示しているコンピューター画面。テキストには、ユーザーが Python と Linux コマンドを操作している様子が示されています。テキストには、subprocess をインポートして実行する Python コードと、「ls」や「vim」などの Linux コマンドが含まれています。
図 7. CVE-2023-44467 の概念実証のスクリーンショット

パロアルトネットワークスは、このセキュリティ問題について、ただちに LangChain チームに連絡しました。この問題に対応し、将来同様のリスクを軽減するため、通知の翌日に LangChain チームは langchain-experimental の pypi ページに警告メッセージを公開しました。

CVE-2023-44467 の緩和策

LangChain Experimental はライブラリーでありその緩和策はライブラリーの使用方法に大きく依存しますが、侵害リスクの緩和方法はあります。プル リクエスト langchain-ai/langchain#11233 はブロックの対象を拡大し、追加の関数やメソッドを含めることで、許可されないコードの実行リスクをさらに緩和しようとするものです。

LLM が生成したコードの使用は、こうしたモデルがセキュリティ上の脆弱性や論理エラーのあるコードを誤って生成する可能性があることから、重大なリスクにつながりかねません。こうしたコードは、安全なコーディング手法に対する深い理解があるわけでなく、トレーニング データのパターンに依存していることから、偏ったコードやコンプライアンスに準拠しないコードを生む可能性があります。こうした生成コードを組み込んだソフトウェア アプリケーションの整合性とセキュリティの確保には、厳格な検証と継続的監視が不可欠です。

結論

AI (とくに LLM) の導入が加速していることから、これらのテクノロジーに内在するリスクの認識が重要となっています。AI ソリューションの導入を急ぐあまりセキュリティ対策の必要性が軽んじられ、それが脆弱性につながって、悪意のある攻撃者に悪用されてしまうことがあります。

サイバーセキュリティ チームにとって、これらのリスクの予測と厳格な防御策の実装は不可欠です。そうすれば、セキュリティ上の弱点を悪用される前に特定して対処することができます。

防御側は、洞察の共有や保護の強化で協力しあうサイバーセキュリティ コミュニティの育成に取り組むのもよいでしょう。そうしたアプローチは、AI テクノロジーの急速な進歩にも対応しうる、打たれ強いサイバー環境の構築にとって不可欠です。

パロアルトネットワークスの保護と緩和策

パロアルトネットワークスのお客様は、Advanced Threat Prevention を含む Cloud-Delivered Security Services (クラウド配信型セキュリティサービス) を有効にした次世代ファイアウォール(NGFW) などの製品によってさらに適切に保護されています。

  • Advanced Threat Prevention のサブスクリプションを有効にした次世代ファイアウォール (NGFW) は、Threat Prevention シグネチャ 95113 を通じたベストプラクティスにより、コマンド インジェクション トラフィックを識別・ブロックできます。
  • Cortex XDR および Cortex XSIAM は多層保護のアプローチにより、エクスプロイト後のアクティビティからの保護に役立ちます。
  • Precision AI™ を搭載した新製品は、AI の生成した攻撃を識別・ブロックし、ポリモーフィック型脅威の加速防止に役立ちます。
  • Prisma Cloud は、クラウド仮想マシンないしプラットフォームに脆弱なバージョンの LangChain がデプロイないし公開されることを検出して防止するのに役立ちます。

侵害の懸念があり弊社にインシデントレスポンスに関するご相談をなさりたい場合は、こちらのフォームからご連絡いただくか、infojapan@paloaltonetworks.comまでメールにてご連絡いただくか、下記の電話番号までお問い合わせください(ご相談は弊社製品のお客様には限定されません)。

  • 北米フリーダイヤル: 866.486.4842 (866.4.UNIT42)
  • EMEA: +31.20.299.3130
  • APAC: +65.6983.8730
  • 日本: (+81) 50-1790-0200

追加リソース

2024-07-24 08:40 JST 英語版更新日 2024-07-23 11:20 PDT の内容を反映

Enlarged Image