Upgrade to Pro — share decks privately, control downloads, hide ads and more …

GraphQLの関連タイプを辿る脆弱性

9cfde65b598c5e2fe8578307bfbad682?s=47 ham
October 04, 2021

 GraphQLの関連タイプを辿る脆弱性

GraphQLのedgeを辿ることで見えてはいけない情報が見えてしまう事象の説明資料

9cfde65b598c5e2fe8578307bfbad682?s=128

ham

October 04, 2021
Tweet

More Decks by ham

Other Decks in Technology

Transcript

  1. GraphQLのedgeを辿ることで 見えてはいけない情報が 見える脆弱性 2021/10/4 LT ham

  2. 前提条件 下記のようなUserとTeamというTypeがあるとします。 Userは複数のチームに所属しており、Teamには複数のユーザーが所属しているとします。 type User { id: ID! name: String!

    teams(afterなど): TeamConnection } type Team { id: ID! name: String! users(afterなど): UserConnection }
  3. 前提条件 Teamを取得するQueryを定義します。 type Query { team(teamId: ID!): Team! } このクエリーはアクセス制御されており、teamIdで指定したチームを閲覧許可された利用者のみが閲覧できるように制御

    しています。
  4. クエリー実行 例えば下記のクエリーでTeamと所属Userを取得することができます。 利用者がteamIdで指定したチームの閲覧権限がなければ取得できないのでアクセス制御も良さそうに見えます。 query Team($teamId: ID!) { team(teamId, $teamId) {

    id name users { edges { node { id name } } } } }
  5. 次のクエリーではどうでしょうか? query Team($teamId: ID!) { team(teamId, $teamId) { users {

    edges { node { teams { edges { node { name users {...略} } } } } } } } } teamIdには閲覧できるチームを指定 →アクセスOK 指定したチームに他チームに所属しているユーザーが含まれている場合、 そのユーザー経由で別チームの情報まで取得することができる。 →トップ階層のアクセス制御だけでなく、関連 Typeのアクセス制御も考慮が 必要
  6. 今後の方針(まだ迷っている...) • DBカラム≒typeのように汎用的にtypeを作った場合、この脆弱性を埋め込 んでしまう可能性が高い。 • クエリーごとにtypeを分ければ発生しないが似たtypeが乱立してしまう。 • Typeを何階層もまとめて取得したいケースはあまりないのではないか?とい う仮説のもと、次ページの方針でしばらく様子を見る。

  7. 今後の方針(まだ迷っている...) • 親子関係の場合、親から子を参照するfieldのみ許可する。 • 親子関係以外の場合、fieldに指定するtypeはスカラー型だけのtypeとす る。さらに先のtypeを取得したい場合は別途クエリーを実行する。 type Team { id:

    ID! name: String! users(afterなど): UserConnection } UserConnectionには別typeのfieldは定義しない。 もしUserに紐づくtypeを取得したい場合は、別途 User主 体のクエリーを実行する。