コンテンツにスキップ

Index

GraphQL API におけるエイリアスオーバーロード

説明

GraphQL のエイリアスオーバーロードは、攻撃者がクエリで大量のエイリアスを使用して、サーバーの処理能力を圧倒した場合に発生します。

GraphQL のエイリアスを使用すると、クライアントは同じフィールドを異なる名前で複数回要求できます。ただし、単一のクエリでエイリアスを過度に使用すると、サーバーのリソースが枯渇し、サービス拒否 (DoS) 攻撃につながる可能性があります。この攻撃により、パフォーマンスが低下したり、サービスが完全に停止したりする可能性があります。 例:

query oxo {
  alias1: __typename
  alias2: __typename
  alias3: __typename
  alias4: __typename
  alias5: __typename
  ...
}

エイリアスオーバーロードのセキュリティへの影響:

  • サービス拒否 (DoS): 大量のエイリアスを含むクエリを送信することにより、攻撃者はサーバーに過剰なリソースを消費させて処理と応答を行わせ、サービスを低下させたりクラッシュさせたりする可能性があります。
  • リソース枯渇: サーバーは多数のエイリアスを処理する計算負荷の処理に苦労し、メモリの枯渇、CPU スパイク、またはパフォーマンスの低下につながる可能性があります。
  • システムの利用不可: エイリアスオーバーロード攻撃が放置されると、GraphQL API が利用できなくなり、すべてのユーザーのサービスが中断される可能性があります。

推奨事項

エイリアスオーバーロード攻撃のリスクを軽減するには、次の手順を実行できます:

  • タイムアウトの実装: クエリのタイムアウトを強制し、解決に時間がかかりすぎるクエリを終了します。最大実行時間を設定することで、エイリアスを悪用して過剰なサーバーリソースを消費するクエリを自動的に終了させ、サービス拒否 (DoS) 攻撃を防ぐことができます。

  • エイリアスの制限: 単一の GraphQL クエリで許可されるエイリアスの数に対するサーバー側の制限を構成します。GraphQL Armor などのツールを設定してエイリアスを制限し、過負荷を防ぐことができます。

  // GraphQL Armor の構成
  GraphQLArmorConfig({
    maxAliases: {
      // プラグインを有効または無効にする | デフォルト: true
      enabled: true,

      // クエリごとに許可されるエイリアスの最大数を設定する | デフォルト: 50
      n: 50,

      // クエリが受け入れられたときに実行するコールバック
      onAccept: [],

      // クエリが拒否されたときに実行するコールバック
      onReject: [],

      // 拒否の詳細をクライアントに伝播する | デフォルト: true
      propagateOnRejection: true,
    }
  })
  import graphql
  from graphql.language import ast
  from graphql.language import parser
  from settings import api

  def validate_aliases(query: str) -> None:
      """
      この検証は、サーバーの過負荷を防ぐために、過剰な数のエイリアスを含むクエリの実行を防ぎます。
      """

      class AliasesParser(parser.Parser):
          def parse_aliases(self) -> list[ast.FieldNode]:
              aliases = 0
              while self.peek(graphql.TokenKind.NAME):
                  aliases += 1
                  if aliases > api.API_MAX_ALIASES:
                      raise graphql.GraphQLError("Exception - Max aliases exceeded")
                  self.parse_field()
              return []

      ast_parser = AliasesParser(query)
      ast_parser.parse_document()

リンク

基準

  • CWE_TOP_25:
    • CWE_400
  • PCI_STANDARDS:
    • REQ_6_2
    • REQ_6_4
    • REQ_11_3
  • OWASP_MASVS_L2:
    • MSTG_PLATFORM_2
  • OWASP_ASVS_L3:
    • V13_4_1
  • SOC2_CONTROLS:
    • CC_2_1
    • CC_4_1
    • CC_7_1
    • CC_7_2
    • CC_7_4
    • CC_7_5
    • CC_9_1
  • HIPAA_CONTROLS:
    • SECURITY212
    • SECURITY213