
2025/12/26 3:06
LangChain の深刻な脆弱性 – CVE‑2025‑68664
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
Summary
LangChainは、
langchain-core のシリアライズ関数(dumps()/dumpd())に欠陥があることを示す重要なアドバイザリ(CVE‑2025‑68664 / GHSA‑c67j‑w6g6‑q2cm)を公開しました。信頼できない辞書で予約キー “lc” を含む場合、適切にエスケープされずにシリアライズされるため、デシリアライズ時に任意のオブジェクト生成が可能になります。これにより、環境変数から秘密情報を抽出(デフォルトで secrets_from_env=True は 2025年12月5日まで)、不安全なコンストラクタ副作用、および最終的には任意コード実行が発生する恐れがあります。
脆弱性は CWE‑502 と分類され、CVSS スコアは 9.3(クリティカル)です。すべてのコアリリース 1.2.5 および 0.3.81 より前が影響を受け、パッチは 2025年12月24日 に公開されました。一般的な脆弱フローにはイベントストリーミング、ロギング、メッセージ履歴/メモリ、キャッシュ、および
RunnableWithMessageHistory や InMemoryVectorStore.load() などの内部パスが含まれます。最も現実的な攻撃ベクトルは、ストリーミング操作中にプロンプトインジェクションを介して LLM 出力フィールド(additional_kwargs、response_metadata)を操作し、シリアライズされたペイロードを再びオブジェクトとしてデシリアライズすることです。これにより、環境変数からヘッダーが埋め込まれたネットワーク呼び出し(例:ChatBedrockConverse)がトリガーされる可能性があります。
影響を受けるホワイトリストクラスは
langchain_core、langchain_openai、langchain_aws、langchain_anthropic などにわたります。LangChainJS も同様のメカニズムを持つ関連アドバイザリ(GHSA‑r399‑636x‑v7f6 / CVE‑2025‑68665)があります。
Cyata は発見に対して $4,000 USD の報奨金を受け取りました—これは LangChain の報奨金プログラムで最高額です。開示タイムラインは以下の通りです:報告提出 2025年12月4日、確認 2025年12月5日、アドバイザリと CVE 公開 2025年12月24日。
世界中で約 8億4700万 ダウンロード(前月は約9800万)があり、影響を受けるバージョンを使用している開発者・データサイエンティスト・企業は、秘密情報の漏洩、不意な副作用、またはシステム全体の乗っ取りリスクを軽減するために直ちにアップグレードすべきです。
本文
Cyata Research:LangChainにおけるLangChainの脆弱性
昨日、LangChainは私が langchain-core で報告した脆弱性(CVE‑2025‑68664 / GHSA‑c67j‑w6g6‑q2cm)について重大なアドバイザリを発表しました。
背景
今年初め、私の研究は「Vault Fault」作業で秘密管理者を破ることに焦点を当てました。これは、最も機密性の高い認証情報を守るために設計されたセキュリティ境界です。繰り返し登場した結論の一つは、プラットフォームが誤って攻撃者が作成したデータを信頼できる構造体として扱うと、その境界がすぐに崩れるということでした。今回「壊れる」対象は秘密管理者ではなく、それらを利用する可能性のあるエージェントフレームワークです。
なぜこの脆弱性が特別な注意を要するか
- 核心問題 – 脆弱なAPI(
/dumps()
)は langchain-core 本体に存在し、ツールのバグや統合時のエッジケースではありません。dumpd() - 広範囲への影響 – ダウンロード量で見ると、LangChain は現在世界で最も広く展開されている AI フレームワークコンポーネントの一つです。2025年12月末時点で公開パッケージのテレメトリは数億インストール(≈847 M 総ダウンロード、過去1か月だけで約98 M)を示しています。
- 微妙なトリガー – 実際に発生するケースでは「攻撃者がシリアライズされたバイナリを送って
を呼ぶ」というよりも、LLM の出力がload()
やadditional_kwargs
などのフィールドに影響し、その後フレームワーク標準機能(ストリーミングログ/イベント)で再シリアライズ・デシリアライズされるケースが多いです。単一のテキストプロンプトが思わぬ複雑な内部パイプラインへと波及します。response_metadata
パッチ – バージョン 1.2.5 と 0.3.81 に修正が含まれています。生産環境で LangChain を使用している場合は、できるだけ早くアップデートしてください。
バグの短い概要
LangChain は内部シリアライズ形式として
'lc' マーカーを持つ辞書を LangChain オブジェクトとみなします。脆弱性とは、dumps() と dumpd() が 'lc' キーを含むユーザー制御の辞書を適切にエスケープしないことでした。攻撃者が LangChain のオーケストレーションループで
'lc' キーを持つコンテンツをシリアライズ・デシリアライズできれば、危険な任意オブジェクトを生成し、多くの攻撃者フレンドリー経路に踏み込む可能性があります。
アドバイザリでは 12 の異なる脆弱フロー が列挙されており、これらは非常に一般的なユースケース(例:イベントストリーミング、ロギング、メッセージ履歴/メモリ、キャッシュ)です。
最も深刻な結果
- 環境変数からの秘密抽出 –
でデシリアライズが行われると(昨日までがデフォルト)。secrets_from_env=True - 事前承認済み名前空間内でのオブジェクト生成(
,langchain_core
,langchain_openai
,langchain_aws
など)で、コンストラクタ側に副作用(ネットワーク呼び出し、ファイル操作)が発生する可能性。langchain_anthropic - 特定条件下での任意コード実行。
CWE‑502:信頼できないデータのデシリアライズ、CVSS 9.3(クリティカル)。
私の研究ストーリー
- 質問から始めました:「AI アプリケーションにおける信頼境界はどこにあり、開発者はそれらを本当に理解しているのでしょうか?」
- デシリアライズを明確な攻撃対象として注目。
- 攻撃者制御のデシリアライズが環境変数を盗み出すブラインド SSRF を誘発できると仮定。
- バグは悪質なコードではなく コードの欠如 でした:
がdumps()
キーを持つユーザー制御辞書をエスケープしませんでした。'lc'
技術的詳細
1. 背景: 'lc'
マーカーとその存在意義
'lc'- LangChain は特定オブジェクトを構造化された dict 形式でシリアライズします。
キーは「これは LangChain シリアライズ構造体です」を示します。'lc'
を含む可能性のあるユーザー制御データは慎重に扱わなければ、攻撃者が内部オブジェクトを装った辞書を作成し、デシリアライザを騙せます。'lc'
2. パッチ
シリアライズ時に
'lc' キーを含む単純な dict をエスケープ(ラップ)することで、実際の LangChain シリアライズオブジェクトとの混同を防止します。
3. ホワイトリスト
/load()
は任意クラスを生成せず、loads()
,langchain_core
,langchain_openai
等のエコシステムパッケージからのクラスのみ許可しています。langchain_aws- ほとんどの許可クラスは安全なコンストラクタですが、一部(例:
) はインスタンス化時にネットワーク呼び出しを行います。ChatBedrockConverse
4. 情報漏洩経路
loads() はデシリアライズ中に環境変数から値を解決する秘密型をサポートします。パッチ前は secrets_from_env がデフォルトで有効でした:
if ( value.get("lc") == 1 and value.get("type") == "secret" and value.get("id") is not None ): key = value["id"] if key in self.secrets_map: return self.secrets_map[key] if self.secrets_from_env and key in os.environ and os.environ[key]: return os.environ[key] # <-- 環境変数を返す
攻撃者は
ChatBedrockConverse のようなクラス(デフォルトホワイトリストに含まれる)を生成し、アウトバウンド GET リクエストを送ることができます。secrets_from_env が有効だと、任意の環境変数をリクエストヘッダーに注入でき、秘密情報が漏洩します。
5. Jinja2 テンプレート経由でのコード実行
クラス(ホワイトリスト内)ではテンプレートからプロンプトを生成し、その一形態として Jinja2 を使用。PromptTemplate- Jinja2 のレンダリングは任意 Python コードを実行できるため、直接的に
で発動するわけではありませんが、デシリアライズ後のオブジェクト呼び出しで実行される可能性があります。loads()
対象範囲 – 実務チェックリスト
アプリケーションが脆弱な langchain-core バージョンを使用している場合に曝露されます。12 の脆弱フローは次のようなパターンです:
(v1 は脆弱、v2 は非脆弱)astream_events(version="v1")Runnable.astream_log()- 信頼できないデータに対する
その後dumps() / dumpd()load() / loads() - デシリアライズ時の信頼できない入力
- 内部シリアライズフロー(
,RunnableWithMessageHistory
, 特定キャッシュ, LangChain Hub のInMemoryVectorStore.load()
等)hub.pull
推奨:パッチ適用済みバージョンへアップグレード。実際に動作している環境が修正コードを使用しているか確認してください。
本番環境での対策 – 防御指針
- まずはパッチ – langchain-core を修正版に更新し、すべての環境でインストールされているバージョンを検証。
- LLM 出力は攻撃者制御とみなす –
,additional_kwargs
, ツール出力, 取得ドキュメント, メッセージ履歴などを、再シリアライズ・ロードされるストリーミングログ/イベントで信頼できないものとして扱う。response_metadata - 秘密解決機能の見直し – アップグレード後は「環境変数から秘密を解決する」設定を無効にしておくか、受け取るデータが安全であることを確認。
LangChainJS の並行ケース
LangChainJS でも類似のアドバイザリ(GHSA‑r399‑636x‑v7f6 / CVE‑2025‑68665)があり、同様のメカニズムです。Python と JavaScript 両方を運用している組織は、このパターンがエコシステム横断で存在することを念頭に置いてください。
LangChain を超えて重要な理由
エージェント型 AI フレームワークは、プロダクションシステム内の重要インフラへと変わっています。シリアライズ形式・オーケストレーションパイプライン・ツール実行・キャッシュ・トレーシングは「配管」ではなく、安全境界そのものです。この脆弱性は単なるライブラリバグではなく、より広いパターンのケーススタディです:
- アプリケーションが安全に生成したと信じるデータをデシリアライズする際、その出力に LLM が生成した不正入力(プロンプトインジェクション等)が含まれる可能性。
- 内部マーカーとして使われる予約キーが、秘密情報や実行近接挙動へのピボット点になる。
AI ガバナンスへの示唆
セキュリティリーダーは次の問いを投げかけるべきです:
- どこでエージェントを使用しているか?
- プロダクションにデプロイされているバージョンは?
- どのサービスが機密秘密へアクセスできるか?
- LLM 出力がその境界を越える場所は?
これらは可視化とガバナンス問題であり、単なる開発者の課題ではありません。
Cyata が提供する支援 – 可視化・リスク評価・制御・ガバナンス
| フォーカス | 提供内容 |
|---|---|
| 可視化 | 実行中のもの、場所、接続状況を把握。フレームワーク、パッケージ、バージョンを追跡。 |
| リスク評価 | 現実世界での爆発半径に基づき優先順位付け。最高リスクパス(信頼できないコンテンツが特権環境へ)を特定。 |
| 制御 | リスクあるパターン(例:信頼できないデータのデシリアライズ)のガードレールを強化。敏感機能を不正な文脈でブロック。 |
| ガバナンス | 承認済みフレームワーク・バージョン・設定に関するポリシー定義、逸脱監視、監査ログ提供。 |
開示タイムライン
- レポート提出(Huntr) – 2025年12月4日
- LangChain メンテナの承認 – 2025年12月5日
- アドバイザリ・CVE 公開 – 2025年12月24日