flawopen.com/AI Security/langgraph-js-custom-auth-cross-user-store-access
LangGraph JS Auth:Store のユーザー間アクセス
langgraph-api 0.15.0未満では、JS/TSカスタム認証が書き換えたStore namespaceを失い、他ユーザーのデータへアクセス可能でした。0.15.0へ更新してください。[1], [2]
図書館で司書が利用証を確認し、別の窓口に本の取得を頼む場面を考えてください。別窓口はあなたの棚番号を書き込みますが、引き継ぎで変更が失われ、訪問者が最初に指定した棚から本を取ってしまいます。影響を受ける JavaScript/TypeScript 認証経路では、認可ランタイムと Store 操作の間で namespace の書き換えが失われる可能性がありました。修正では認可済み namespace を引き継ぎ、Store の使用前に検証します。[1]
主要な概念と専門用語
GHSA-4hm6-w6qq-w73v- 2026年9月28日に公開された LangGraph の高重要度アドバイザリです。CVE は割り当てられていません。対象パッケージは langgraph-api で、0.15.0 で修正されています。[1]
Store namespace- LangGraph Store のレコードをまとめる階層名です。データ分離のためユーザーやテナントの識別子を含めることがあります。[1]
カスタム認可ハンドラー- 認証済みリクエストのリソースアクセス可否を決め、Store 操作前に namespace を書き換えることもできるアプリケーションコードです。[1]
フレームワーク対応
ステップ・バイ・ステップの攻撃フロー
デプロイが条件に該当するか確認
langgraph-api が >=0.1.2 かつ <0.15.0 で、サーバーが JavaScript または TypeScript のカスタム認証ハンドラーを使うか確認します。[1]
namespace の書き換えを特定
ハンドラーが範囲外の要求を拒否せず、認証済みユーザーの識別子を含める、または強制するため要求 namespace を変更します。[1]
認可結果がランタイム境界を越える
影響を受けるバージョンでは namespace の変更が Store 操作へ伝わらない可能性があり、要求者が指定した元の namespace が使われることがあります。[1]
認証済みユーザーが別の namespace を指定
一般ユーザーが自身の namespace 外の Store レコードに対する操作を要求できます。アドバイザリでは読み取り、上書き、検索、削除が挙げられています。[1]
根本原因の分析 (Root Cause)
LangGraph メンテナーが2026年9月28日に公開した GHSA は、langgraph-api >=0.1.2 かつ <0.15.0 の不具合を説明しています。影響には次の条件がすべて必要です。JavaScript または TypeScript のカスタム認証を使用し、Store 認可ハンドラーが現在のユーザーにデータを制限するため要求 namespace を書き換え、通常の認証済みユーザーが Store 操作を送信でき、その認可経路を複数ユーザーのデータが通ることです。アドバイザリによれば、Python のカスタム認証ハンドラーは対象外です。また、JavaScript/TypeScript ハンドラーが namespace を書き換えるのではなく未許可リクエストを拒否する場合も対象外です。ハンドラーによる namespace の変更がランタイム境界で失われ、Store 操作が元の要求 namespace を使う可能性がありました。認証済みユーザーが許可された namespace 外のレコードを読み取り、上書き、検索、削除できるおそれがあります。これはログインを回避するものでも未認証のリモート攻撃でもありません。アドバイザリは High、CVSS 4.0 8.6 と評価し、CWE-639 と CWE-863 を割り当てています。0.15.0 はハンドラーの変更を境界越しに渡し、結果の namespace を検証し、不正または安全に適用できない変更を拒否します。アップグレードまでの回避策は、すべての Store 操作で未許可 namespace を拒否することです。コードはデータフローを示す簡略 TypeScript 例であり、SDK の実ソースではありません。[1]
ソースコード比較:脆弱 vs 堅牢化
この簡略 TypeScript 例は境界の契約を示すもので、関数名と結果の形式は説明用です。LangGraph SDK の実ソースではありません。アドバイザリは JS/TS の認可変更が Store 操作前に失われる可能性を確認していますが、この内部実装そのものは公開していません。したがって脆弱側は、Store が認可済み namespace ではなく要求 namespace を使うという、文書化された不変条件のみを示します。修正版は認可結果を受け取り検証します。メンテナーが示す回避策は、すべての Store 操作で未許可 namespace を書き換えずに拒否することです。[1]
ソース抜粋: LangGraph API の認可と Store の境界 — 簡略化した契約例
type StoreRequest = { namespace: string[]; key: string };
type AuthorizationResult = { allowed: boolean; namespace: string[] };
async function readStore(userId: string, request: StoreRequest) {
const authorization = await authorizeStore(userId, request); // Illustrative bridge contract.
return store.get(request.namespace, request.key); // The bridge drops the authorized result.
}
type StoreRequest = { namespace: string[]; key: string };
type AuthorizationResult = { allowed: boolean; namespace: string[] };
async function readStore(userId: string, request: StoreRequest) {
const authorization = await authorizeStore(userId, request); // Illustrative bridge contract.
if (!authorization.allowed) throw new Error("forbidden");
const namespace = validateAuthorizedNamespace(userId, authorization.namespace);
return store.get(namespace, request.key); // Apply the authorized result.
}
エンジニアリング&システム堅牢化チェックリスト
- ✓
langgraph-apiのバージョンを棚卸しし、JavaScript/TypeScript のカスタム認証を使うデプロイを特定します。Python ハンドラーはこのアドバイザリの対象外です。[1] - ✓影響を受けるデプロイを
langgraph-api>=0.15.0に更新し、ロックファイルやソースブランチだけでなく実際の配備成果物を確認します。[1], [2] - ✓更新まで、各 Store 認可ハンドラーで認証済みユーザーの namespace 外の要求を拒否します。失われる可能性がある書き換えだけに依存しないでください。[1]
- ✓2つのテストIDを使い、
get、put、search、delete、namespace 一覧を検証します。各操作が認可 namespace に限定され、ユーザー間アクセスが拒否されることを確認してください。[1] - ✓利用可能な Store のアクセス・変更ログを確認し、他ユーザーの namespace に対する読み取り、検索、書き込みを調べます。不正な変更が見つかった場合は証拠を保全し、修復前に影響を受けたレコードを評価します。[1], [5]