フェデレーテッドサブグラフインジェクション:"盲目"なGraphQLデータ漏洩

企業がモノリシックアーキテクチャからフェデレーテッドGraphQL(スーパグラフ)へ積極的に移行する中、新たで重大な脆弱性クラスが出現しています:フェデレーテッドサブグラフインジェクション。APIゲートウェイを強化する一方で、多くの組織はアーキテクチャのソフトな部分 — サブグラフ自体を見落としがちです。この脆弱性は、ゲートウェイとサブグラフ間の暗黙の信頼を悪用し、攻撃者がプライベートマイクロサービスから敏感なデータ断片を「ステッチ」して結合できるようにします。この記事では、攻撃の仕組み、従来のWAFでは見えない理由、そしてData GraphのためのZero Trustアーキテクチャの実装方法について解説します。
スーパグラフの台頭とセキュリティギャップ
現代のAPI環境では、Apollo Federation、Hasura、WunderGraphなどにより普及したGraphQL Federationは、複数のマイクロサービス(サブグラフ)を単一のクエリ可能なエンドポイント(スーパグラフまたはゲートウェイ)に統合する標準となっています。
信頼のアーキテクチャ
典型的なフェデレーテッド設定では:
- ユーザーがゲートウェイにクエリを送信
- ゲートウェイはJWTを検証し、高レベルの権限を確認し、クエリプランを構築
- ゲートウェイはクエリを断片に分割し、それぞれのサブグラフ(例:ユーザーサービス、請求サービス、在庫サービス)に送信
- サブグラフは自分の部分を実行し、JSONを返す
- ゲートウェイは結果を「ステッチ」してユーザーに返す
致命的な欠陥: 多くのエンジニアはサブグラフを「内部」とみなし、安全だと考えています。リクエストがサブグラフに到達した時点でゲートウェイが既に認証済みと想定しているためです。その結果、サブグラフはしばしば自身の認証チェックを省略し、典型的なConfused Deputy問題を引き起こします。
フェデレーテッドサブグラフインジェクションとは何か?
フェデレーテッドサブグラフインジェクションは、サーバー側の脆弱性であり、攻撃者がGraphQLクエリの構造を操作して、ゲートウェイに悪意のあるクエリ断片を脆弱なサブグラフに注入させるものです。
サブグラフはゲートウェイが唯一の呼び出し元と想定しており、「スマート」なものと信じているため、敏感なフィールド(PII、内部ID、管理フラグなど)へのリクエストを無検証で実行します。
なぜ「盲目」なのか?
「盲目」という用語は、二つの異なる失敗モードを指します:
ゲートウェイの盲目さ: ゲートウェイは構文的に有効なクエリを見て、「問題ない」と判断します。グローバルスキーマを確認し、「これで良い」と言いますが、実際のビジネスロジックの制約は理解していません。
サブグラフの盲目さ: サブグラフは、「User ID 123のSSNをください」といったリクエストを受け取りますが、元のクライアントのトークンやコンテキストを見ておらず、信頼しています。リクエストがゲートウェイのIPから来たと信じているのです。
攻撃の構造
シナリオ:”ステッチされた”アイデンティティ漏洩
スーパグラフには二つのサブグラフがあります:
- ユーザーサブグラフ: 公開プロフィールデータを扱う
- 請求サブグラフ: プライベートなクレジットカード情報や請求書を扱う
ユーザーサブグラフは以下を定義:
type User @key(fields: "id") {
id: ID!
username: String
# 公開情報のみ
}
請求サブグラフはUser型を拡張:
extend type User @key(fields: "id") {
id: ID! @external
last4Digits: String
invoices: [Invoice]
# 機密情報:本人のみが閲覧可能
internalRiskScore: Int
}
脆弱性
ゲートウェイはinvoicesをクエリするにはログインが必要としますが、internalRiskScoreフィールドには@authディレクティブが付いていません。これは開発者が”内部フィールドだからゲートウェイは公開しない”と想定していたためです。
スキーマの構成ミスや、Fragment Injectionを利用した攻撃により、ゲートウェイの表面検査を回避できる場合があります。
攻撃クエリ例
query LeakRiskScore {
node(id: "User:123") {
... on User {
username
_onBilling_internalRiskScore: internalRiskScore
}
}
}
実行の流れ
- ゲートウェイは
Nodeへのリクエストを検知し、IDを解決 - クエリプランナーは
internalRiskScoreが請求サブグラフにあると認識 - インジェクション: ゲートウェイは請求サブグラフへのフェッチリクエストを生成:
query {
_entities(representations: [{ __typename: "User", id: "123" }]) {
... on User {
internalRiskScore
}
}
}
- 請求サブグラフはリクエストを受け取り、
internalRiskScoreをID 123のユーザーに対して返します。現在のユーザーが本人かどうかの検証は行いません。 - 漏洩: 請求サブグラフはスコア
99(高リスク)を返します。 - レスポンス: 攻撃者はプライベートデータを取得します。
実際のCVE:理論だけではない
この攻撃パターンは、2025年後半に複数の高深刻度のCVEとしてApollo Federationに対して公開されました。これは最も広く展開されているフェデレーテッドGraphQLランタイムです。
CVE-2025-64530 — インターフェースアクセス制御回避(2025年11月)
深刻度:高
Apollo Federationの構成ロジック(バージョン2.9.5以前、2.10.4、2.11.5、2.12.1)に脆弱性があり、インターフェース型やフィールドのアクセス制御を回避できました。Apollo Federationは、ユーザー定義のアクセス制御ディレクティブ(@authenticated、@requiresScopes、@policy)をインターフェース型に誤って許可していました。GraphQL仕様では、インターフェースから実装型への継承ルールが定義されていないため、これらのディレクティブは伝播されません。
攻撃者は、インラインまたは名前付きフラグメントを使って、インターフェースに設定された制御を完全に回避しながら、実装オブジェクト型を通じて保護されたデータにクエリを送ることができました。パッチは、インターフェース型に対するユーザー定義のアクセス制御ディレクティブを完全に拒否し、フェデレーションの構成ロジックが自動的に適切なディレクティブを生成するようにしました。
対策: Apollo Federation構成を2.9.5以上にアップグレード、または2.10.4、2.11.5、2.12.1にアップデート。未パッチの場合は、インターフェース型から実装型へのアクセス制御要件を手動でコピーしてください。
CVE-2025-64173 — 多相型認可失敗
深刻度:高
Apollo Router Coreのバージョン1.61.11以下(および2.0.0-alpha.0から2.8.1-rc.0まで)では、インターフェース型とその実装オブジェクト型のアクセス制御ディレクティブの処理に誤りがありました。すべての実装が同じ要件を共有している場合、Routerはインターフェースにディレクティブを適用し、実装型のディレクティブを無視しました。これにより、追加のアクセス制御が必要なデータに未認証のクエリがアクセスできてしまいました。
対策: Apollo Routerを1.61.12または2.8.1にアップグレード。
CVE-2025-64347 — リネームされたディレクティブの回避
深刻度:高
Apollo Router Coreのバージョン1.61.12-rc.0以下では、@linkインポートによるリネームされたアクセス制御ディレクティブが適用されませんでした。スキーマ構成の一環として@authenticatedをカスタム名にエイリアスした場合、Routerはそのディレクティブを強制しませんでした。修正はバージョン1.61.12と2.8.1で提供済みです。
GHSA-m8jr-fxqx-8xx6 — 推移的フィールドアクセス制御回避
フェデレーションの構成ロジックにおいて、@requiresや@fromContextを使ったフィールドが、保護されたデータに依存している場合、その依存フィールドと同じアクセス制御要件を持つ必要があります。攻撃者は、依存フィールドだけをリクエストし、実際に保護されたフィールドをリクエストしなくても、アクセス制御を回避できます。修正は、依存フィールドが参照するフィールドと同じアクセス制御を持つことを強制します。
攻撃のバリア:ダイレクトサブグラフ露出(”シャドウグラフ”)
ゲートウェイが完璧にセキュアでも、多くの組織はサブグラフエンドポイント(例:billing-service.internal:4000/graphql)を誤って公開しています:
- 誤設定されたロードバランサやIngressコントローラー
- 隣接サービスのサーバーサイドリクエストフォージェリ(SSRF)脆弱性
- DMZから到達可能な予測可能な内部DNS名
Apolloのセキュリティガイダンスによると、サブグラフが直接アクセス可能な場合、ルーターのセキュリティ制御を完全に回避します。_entitiesクエリは、フェデレーテッドデータを取得するための特別なクエリですが、これが認証なしで誰でもアクセスできるデータアクセス手段となります。
攻撃者がサブグラフに直接到達できる場合、ゲートウェイのリクエストを模倣できます:
POST http://billing-service.internal:4000/graphql
{
"_entities": [{ "__typename": "User", "id": "456" }],
"query": "query { _entities(representations: [{ __typename: \"User\", id: \"456\" }]) { ... on User { internalRiskScore invoices { amount } } } }"
}
JWTも認証ヘッダーも不要です。内部アクセスの生のリクエストです。
なぜ従来のWAFはこれを見逃すのか
Webアプリケーションファイアウォール(WAF)は主にHTTPリクエストの署名(URLパターン、ペイロード、既知の悪意のある文字列)に基づいて動作します。フェデレーテッドサブグラフインジェクションは以下を生成します:
- 構文的に有効なGraphQLクエリ
Content-Type: application/jsonを含む標準的なPOST /graphqlリクエスト- SQLやシェルコマンド、従来のインジェクションペイロードは含まれません
- ゲートウェイのログから見て”成功”と見なされるリクエスト(
200 OKレスポンス)
これにより、ゲートウェイのアクセスログには異常が記録されません。 この侵害は、サブグラフ自体がリクエストの不正を認識しないため、すべての層で見えなくなります。これはコンプライアンスの問題の核心であり、GDPRやCCPAの監査では、正当なユーザーリクエストが200を返し、どのサブグラフフィールドが実際に返されたかの記録が残らないことになります。
深層防御:スーパグラフのセキュリティ
“ゲートウェイトラスト”から”ゼロトラスト”へ移行するには、すべての層で制御を行う必要があります。
1. サブグラフレベルの認証(ゴールデンルール)
ゲートウェイだけに頼らず、各サブグラフが独立してユーザーを検証し、特定のオブジェクトへのアクセス権を確認する必要があります。
// 請求サブグラフのリゾルバ例
const resolvers = {
User: {
internalRiskScore: async (userEntity, args, context) => {
// 重要:リゾルバレベルで認証を検証
if (context.userId !== userEntity.id && !context.isAdmin) {
throw new AuthenticationError("リスクスコアの閲覧権限がありません");
}
return fetchRiskScore(userEntity.id);
}
}
};
contextオブジェクトは、ゲートウェイからサブグラフへリクエストごとにJWTを伝播させて設定します。これは絶対に必要です。
2. ゲートウェイとサブグラフ間の通信のセキュリティ
サブグラフは正当なゲートウェイからのリクエストのみ受け付けるべきです。選択肢は二つ:
Mutual TLS (mTLS): 最も強力な防御策。サブグラフはゲートウェイに発行されたクライアント証明書のみを受け入れます。攻撃者や誤設定のSSRFからのリクエストはTLSハンドシェイクで拒否されます。
HMAC署名リクエスト: ゲートウェイは共有シークレットでサブグラフへのリクエストに署名し、サブグラフは署名を検証します。単純な静的ヘッダー(例:x-gateway-secret: "hardcoded-value")は不十分です。秘密情報はソースコードやログ、環境ダンプに漏れる可能性があります。
3. ネットワーク分離 — サブグラフは内部に限定
Apolloの公式セキュリティドキュメントでも強調されている通り、サブグラフはルーターからのみアクセス可能にすべきです。パブリックインターネットやDMZセグメント、ゲートウェイ以外のサービスからはアクセスさせてはいけません。これをネットワークレベル(セキュリティグループ、VPCポリシー、KubernetesのNetworkPolicy)で強制します。
4. _serviceと_entitiesの公開エンドポイントを無効化
_serviceフィールドはサブグラフのSDL(スキーマ定義言語)を公開します。_entitiesはフェデレーションクエリのエントリポイントです。どうしても外部公開が必要な場合は、信頼できるゲートウェイIPからのリクエスト以外はこれらのフィールドをブロックするミドルウェアを使用してください。
5. パッチ適用と最新状態の維持
上記のCVEは、フェデレーションランタイムの設計ミスも含め、構成レベルの脆弱性を示しています。次のことを行いましょう:
- Apollo Routerやフェデレーション構成、使用しているライブラリのセキュリティアドバイザリを監視
apollo checkやrover subgraph checkをCI/CDパイプラインに組み込み、スキーマのアクセス制御の問題を事前に検出- GraphQL InspectorやApollo GraphOS schema checksを使い、公開されているが敏感な型を返すフィールドを特定
6. @requiresや@fromContext依存関係のアクセス制御強化
GHSA-m8jr-fxqx-8xx6に従い、@requiresや@fromContextを使ったフィールドを監査し、保護されたデータに依存するフィールドには一致したアクセス制御ディレクティブを付与してください。修正済みの構成ライブラリは自動的にこれを強制しますが、古いバージョンを使う場合は手動で確認が必要です。
7. サブグラフでのクエリコスト分析
攻撃者はフェデレーションインジェクションを利用して、深くネストされた関係をリクエストし、サービス拒否(DoS)攻撃を仕掛けることも可能です。クエリの深さ制限やコスト分析をサブグラフレベルで実施し、不正なエンティティクエリによるリソース枯渇を防ぎましょう。
ビジネスとコンプライアンスへの影響
フェデレーテッドサブグラフインジェクションの成功は、即時のデータ漏洩だけでなく、ビジネスに深刻な影響を及ぼします:
データ漏洩: メールアドレス、ID、金融データなどのPIIが、保護されていると信じられていたサービス間で漏洩します。
コンプライアンス違反: ゲートウェイのログには200 OKが記録されるため、不正アクセスの監査証跡が残りません。GDPRやCCPAの調査では、アクセス制御が適切に行われていたことを証明できない可能性があります。
評判の損失: フェデレーテッドアーキテクチャはスケーラビリティのために採用されますが、この層での侵害は、スーパグラフ内のすべてのサービスに影響を及ぼす可能性があります。
まとめ
フェデレーテッドGraphQLは開発速度を大きく向上させますが、従来のセキュリティ境界を根本的に破壊します。フェデレーテッドサブグラフインジェクションは、「スマートゲートウェイ」と「ダムサブグラフ」の間のギャップを狙います。2025年後半に公開されたCVEは、主要なフェデレーションランタイムの構成ロジックにアクセス制御の回避をもたらす脆弱性が存在することを示しています。
重要な原則はシンプルです:認証ロジックはデータとともに移動すべきであり、リクエストだけに付随すべきではありません。 セキュリティチームはスーパグラフを監査し、すべてのサブグラフを公開サービスとみなして、各層でアクセス制御を確実に実施してください。
Related InstaTunnel pages
Continue from this article into the most relevant product guides and workflows.
Related Topics
Keep building with InstaTunnel
Read the docs for implementation details or compare plans before you ship.