FlawOpen

flawopen.com/AI Security/langgraph-js-graph-input-control-directive-october-2026

● CWE-20 · CVSS v4 7.6[1] · 高
セキュリティ研究 · FlawOpen

GHSA-wp87-994x-j95x:JSONをグラフ命令と誤認

LangGraph.js <1.4.21は通常のJSONを制御命令として扱い、検証や承認ノードを迂回する可能性がありました。更新し、サーバー側で状態を検証してください。[1]

CVSS ベクトルCVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N[1]
💡 わかりやすい解説 (ELI5)

グラフを駅にたとえると、荷物は乗車前に検査されます。影響を受ける版では「Command」と書かれた荷札を、線路を切り替える権限付き命令と誤認する可能性がありました。修正により通常のオブジェクトとCommandは区別されますが、アプリは各機密操作の前に権限を確認する必要があります。[1], [2]

主要な概念と専門用語

GHSA-wp87-994x-j95x
LangChainが2026年10月8日に公開したHighのアドバイザリ。CVSS 4.0は7.6、CWE-20、既知のCVEなし。[1]
グラフ入力
LangGraph.jsの実行に渡す状態オブジェクト。サーバー側で検証し、許可フィールドだけを選びます。[1]
Command
状態更新や実行経路の指定を行うLangGraph.jsオブジェクト。通常のJSONはデータとして扱います。[2]
制御境界
アプリケーションデータがノード選択や状態変更の命令として解釈される境界。[1]

フレームワーク対応

  • このガイドで説明する弱点の CWE 参照: CWE-20

ステップ・バイ・ステップの攻撃フロー

ステップ 1

アプリが呼び出し元のJSONを受け取る

影響する構成では、検証済み状態をサーバーで作らず、信頼できないJSONを直接グラフへ渡します。[1]

ステップ 2

データが制御オブジェクトと誤認される

1.4.21より前はlg_nameだけで通常オブジェクトがCommandに見える可能性がありました。問題はJSON解析ではなく型判定です。[1], [2]

ステップ 3

通常の処理経路が省略される

状態更新やルーティングとして処理され、アプリ定義の検証・承認ノードを迂回するおそれがあります。[1]

ステップ 4

ツール権限が影響を左右する

機密ツールがある場合、アドバイザリはアプリ権限で不正実行が起き得ると説明します。操作境界で再認可してください。[1]

根本原因の分析 (Root Cause)

アドバイザリの対象は @langchain/langgraph >=0.2.23 かつ <1.4.21です。アプリが信頼できないJSONを直接グラフへ渡し、通常の実行経路で検証や認可が行われると依存している場合に影響します。修正PRによると、以前のisCommandはlg_nameフィールドだけで値を判定していたため、通常のJSONもCommandとして扱われる可能性がありました。その結果、アプリ定義の検証・承認ノードより前にupdateやgotoが適用され得ます。機密ツールがある場合、アプリの権限で未認可の実行につながる可能性があります。1.4.21は通常オブジェクトをCommandとして拒否し、本物のインスタンスは引き続き扱います。これはサーバー側の状態構築、許可フィールドの限定、各操作での認可に代わりません。CWE-20、High、CVSS 4.0 7.6で、既知のCVEはありません。[1], [2]

ソースコード比較:脆弱 vs 堅牢化

この縮約TypeScript例はPR #2966の変更を表します。lg_nameだけでは通常オブジェクトをCommandと判定しません。逐語的なソース抜粋でも完全な実装でもありません。修正後、解析済みJSONは通常の状態経路に進み、本物のCommandオブジェクトはグラフを制御できます。オブジェクトの形を認可の代わりにしないでください。サーバーで許可フィールドから状態を作り、機密操作ごとに認可してください。[2]

ソース抜粋: LangGraph.js Command判定の動作を示す縮約例。完全なソースコードではありません

脆弱な実装
type CommandLike = { lg_name: string; goto?: unknown; update?: unknown };

function isCommand(value: unknown): value is CommandLike {
  return typeof value === "object" && value !== null &&
    "lg_name" in value && value.lg_name === "Command";
}
堅牢化されたセキュアパッチ
type CommandLike = { lg_name: string; goto?: unknown; update?: unknown };

function isPlainObject(value: object): boolean {
  const prototype = Object.getPrototypeOf(value);
  return prototype === Object.prototype || prototype === null;
}

function isCommand(value: unknown): value is CommandLike {
  return typeof value === "object" && value !== null &&
    !isPlainObject(value) &&
    "lg_name" in value && value.lg_name === "Command";
}

エンジニアリング&システム堅牢化チェックリスト

参考資料

← AI Security Directory →