0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GraphQL APIで「一部だけの個人情報露出」が重大インシデントになり得る理由

0
Last updated at Posted at 2026-05-13

GraphQL APIで「一部だけの個人情報露出」が重大インシデントになり得る理由

はじめに

GraphQLは柔軟なAPI設計が可能である一方で、
「本来返却されるべきではないフィールド」が露出しやすい構造でもある。

今回は、バグバウンティ調査中に遭遇した「firstNameのみが完全表示されていたケース」をベースに、
なぜ“たった一部の情報”でもセキュリティリスクになり得るのかを解説する。

※ 本記事は実際の調査経験を元に一般化・匿名化した内容である。
対象サービス名・ユーザー情報・識別子等はすべてマスクしている。


発見した問題

あるGraphQL APIにおいて、本来はイニシャル表示のみを想定していたユーザー情報が、
APIレスポンス上では完全な firstName として返却されていました。

想定されていた表示

{
  "firstName": "H.",
  "lastName": "D."
}

実際のレスポンス

{
  "firstName": "Hogehoge",
  "lastName": "D."
}

lastName側はマスクされていた一方で、firstNameのみ完全表示されていたため、
privacy masking が片側だけ実装されている状態でした。


なぜ危険なのか?

一見すると、

「firstNameだけなら大したことないのでは?」

と思われるかもしれない。

しかし実際の攻撃では、“単体情報”ではなく“情報の相関”が重要になる。

今回のケースでは、以下のような情報を組み合わせることが可能であった。

  • firstName
  • ユーザーUUID
  • avatar URL
  • レビュー履歴
  • 投稿店舗情報

これにより、同一人物のレビュー活動を追跡できる状態となっていた。


攻撃者視点で見るとどうなるか

1. 同一人物の追跡

UUIDが固定で返却されていたため、複数レビューを横断して同一人物を追跡可能であった。

例:

  • 東京の高級レストラン
  • 横浜のバー
  • 大阪旅行時の店舗

などを時系列で紐付け可能になります。


2. 実在人物の特定

avatar画像やレビュー内容を組み合わせることで、SNSアカウントやGoogleプロフィールと関連付けられる可能性がある。

特に:

  • ニックネーム
  • 顔写真
  • 行動パターン
  • 利用地域

が重なると、現実の人物特定に繋がるケースがあります。


3. ソーシャルエンジニアリング

以下のような情報が揃うと、標的型攻撃の材料になります。

  • よく利用する地域
  • 趣味嗜好
  • 食事傾向
  • 活動時間帯

つまり、単なる「名前漏洩」ではなく、“ユーザープロファイリング”が可能となる。


なぜGraphQLで起きやすいのか

GraphQLでは、クライアント側が必要フィールドを自由に指定できます。

例えば:

query {
  reviews {
    reviewer {
      id
      firstName
      lastName
    }
  }
}

この柔軟性は便利である一方、サーバー側で適切なフィールド制御を行わない場合、
「フロントでは非表示想定だった情報」がAPI経由で露出する。


よくある実装ミス

フロントエンド側のみでマスク

const masked = user.firstName[0] + ".";

この場合、API自体はフルデータを返却しているため、
GraphQL ExplorerやDevToolsから容易に確認可能となる。


どうすれば防げるのか

今回のような問題を防ぐためには、フロントエンド側ではなく、APIレベルでの制御が必要となる。

1. APIレスポンス側でマスキングを行う

フロントエンド側のみでマスキングを実施すると、GraphQL API自体からはフルデータが取得できてしまう。

そのため、以下のようにサーバー側で加工済みデータを返却するべきである。

{
  "firstName": "H.",
  "lastName": "D."
}

2. 不要なフィールドを返却しない

GraphQLでは「取得可能であること」自体がリスクになる。

そのため:

  • avatar URL
  • internal UUID
  • tracking可能な識別子
  • internal metadata

などは、本当に必要な場合のみ返却すべきである。


3. Field-level authorization を導入する

GraphQLでは、Query単位だけでなくField単位での認可制御が重要となる。

例えば:

  • 未認証ユーザー
  • 一般ユーザー
  • 管理者

で取得可能フィールドを分離する必要がある。


4. 「組み合わせ」を前提に設計する

セキュリティレビューでは、単体データだけではなく、
「他データと組み合わせた時に何が起こるか」を考慮する必要がある。

特に:

  • UUID
  • avatar
  • 行動履歴
  • location情報

などは相関分析されやすい。

privacy-by-designの観点からも、最小限の情報返却を徹底すべきである。


実際の評価で印象的だったこと

今回興味深かったのは、露出していた情報自体は一見すると限定的に見えた点である。

{
  "firstName": "Hogehoge",
  "lastName": "D."
}

しかし実際には、

  • UUID
  • avatar URL
  • review履歴
  • restaurant情報

などと組み合わせることで、ユーザーの行動追跡や実在人物との関連付けが可能な状態となっていた。

結果として、この問題は実際のバグバウンティプログラム上で高い優先度(P2)として扱われた。

ここで重要だったのは、

「漏えいしている情報の量」

ではなく、

「その情報が攻撃者にどう利用されるか」

である。

セキュリティレビューでは、
単体では些細に見える情報でも、
相関分析やOSINTと組み合わせることで重大インシデントにつながるケースが存在する。


学んだこと

今回のケースで重要だったのは、
「単体では弱く見える情報でも、組み合わせると高リスクになる」という点である。

セキュリティでは、

  • 情報の量

よりも、

  • 情報同士の関連性
  • 攻撃者がどう利用できるか

の方が重要になるケースがある。

特にGraphQLでは、

  • 過剰なフィールド返却
  • hidden field exposure
  • フロント依存のマスキング

が発生しやすいため注意が必要である。


まとめ

今回のような問題を防ぐためには、フロントエンド側ではなく、APIレベルでの制御が必要となる。

1. APIレスポンス側でマスキングを行う

フロントエンド側のみでマスキングを実施すると、GraphQL API自体からはフルデータが取得できてしまう。

そのため、以下のようにサーバー側で加工済みデータを返却するべきである。

{
  "firstName": "H.",
  "lastName": "D."
}

2. 不要なフィールドを返却しない

GraphQLでは「取得可能であること」自体がリスクになる。

そのため:

  • avatar URL
  • internal UUID
  • tracking可能な識別子
  • internal metadata

などは、本当に必要な場合のみ返却すべきである。


3. Field-level authorization を導入する

GraphQLでは、Query単位だけでなくField単位での認可制御が重要となる。

例えば:

  • 未認証ユーザー
  • 一般ユーザー
  • 管理者

で取得可能フィールドを分離する必要がある。


4. 「組み合わせ」を前提に設計する

セキュリティレビューでは、単体データだけではなく、
「他データと組み合わせた時に何が起こるか」を考慮する必要がある。

特に:

  • UUID
  • avatar
  • 行動履歴
  • location情報

などは相関分析されやすい。

privacy-by-designの観点からも、最小限の情報返却を徹底すべきである。


まとめ

今回のケースでは:

  • firstName
  • UUID
  • avatar
  • review history

を組み合わせることで、単なる表示ミスではなく、
「個人追跡・プロファイリング」に繋がるリスクが存在していました。

GraphQLを利用する場合は、- APIレベルでのマスキング

  • 必要最小限のフィールド返却
  • フィールド単位の認可制御
  • privacy-by-design

を徹底することが重要である。


おわりに

バグバウンティを始めた当初は、
「Criticalな脆弱性を見つけないと意味がない」と考えていました。

しかし実際には、

  • 情報をどう組み合わせるか
  • 攻撃者視点でどう見えるか
  • その情報が何に悪用されるか

を考えることの方が、はるかに重要であると感じた。

特にGraphQLは、
「便利さ」と「情報露出」が非常に近い場所に存在するため、
今後も継続的に研究していきたい分野である。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?