🍒

GraphQL脆弱性

2022/06/12に公開

GraphQLの脆弱性についての備忘録

イントロスペクションクエリによるスキーマの流出

  • イントロスペクションクエリは開発時には便利だが開発者以外に漏洩する状態はリスク
    • 例えばUserの中にpasswordフィールドが含まれていた場合、クライアントで呼び出していないからOKとはならない。第三者はイントロスペクションクエリを発行してパスワードフィールドを取得しようとするため
  • 本番環境では第三者に閲覧できないようにする or クエリ自体の実行を無効にしておく
  • Appllo Serverの場合は { introspection: false } オプションで起動する & NODE_ENVをproduction にしておく

IDOR(Insecure Direct Object References)

Userに対してIDで検索するという場合、第三者にIDで検索されて問題ないかを確認すること
もし、ID検索を制御したい場合はAuthorizationヘッダーを利用して自身のIDかどうかのチェックをリゾルバ内で行うこと

再帰的なクエリによる負荷

Userの中にFriendがあり、Friendの中にUserがある場合
Queryをネストすることで、データを再帰的に取得できる
ネストの深さによってデータ量は指数関数的に増加する
攻撃者はこれを利用することでDoS攻撃行うことができてしまう

対策としては

  • タイムアウトを入れる
    • タイムアウトを入れても、悪意のあるクエリの実行は避けられないためサーバーへの一定の負荷は残ってしまう
    • 実装はしやすい
  • クエリの深さを制限する
    • クエリ実行前に深さをチェックするのでタイムアウトに比べてサーバーへの負荷は避けられる
    • 他の正しい深いクエリにも影響が出てしまうのが難点
  • クエリの長さに制限を入れる
    • コストは低いが、実際にはタイムアウトやクエリの深さと一緒に実装することになる
  • クエリのホワイトリスト化
    • GraphQLのクエリではなく、クエリのハッシュ(Persited Query)をクライアント・サーバー間でやりとりする方法
    • ホワイトリスト化することでDoSは防ぐことが可能だが、GraphQLの特徴である柔軟なクエリ設計ができなくなる
    • 実装時は結構ややこしい。そのため、フレームワークによってはフォローしてくれるものもあるので事前に確認すべし

SQLインジェクション

大抵のアプリケーションはバックエンドにDBを利用している
SQL、NoSQLに関わらず、ユーザーからの入力値は信用しないこと
ちゃんとエスケープを行いクエリを発行すること

その他

schema.graphqlからのドキュメント生成ツール

Discussion