コンテンツにスキップ

Object Limit Overriding in GraphQL

GraphQL におけるオブジェクト制限のオーバーライド

説明

GraphQL におけるオブジェクト制限のオーバーライド(Object Limit Overriding)とは、攻撃者がクエリ引数を操作して API の意図された制限を超えることができる脆弱性を指します。これには多くの場合、ページネーションまたは制限パラメーターに極端に大きな値を渡すことが含まれ、結果としてサービス拒否(DoS)攻撃や過剰なリソース消費につながる可能性があります。

潜在的なリスク:

サービス拒否(DoS): 過剰な数のオブジェクトを要求することで、攻撃者はサーバーを過負荷にし、パフォーマンスの低下や停止を引き起こす可能性があります。

リソースの枯渇: 膨大な数のオブジェクトを要求するクエリは、サーバーのメモリと処理能力を過負荷にする可能性があります。

データ漏洩: 場合によっては、制限をバイパスすることで、大量のデータへの不正アクセスにつながる可能性があります。

コストの増加: クラウドベースのサービスの場合、極端に大きな制限を持つクエリを処理すると、リソースの使用率が高くなり、予期しないコストが発生する可能性があります。

脆弱なクエリの例:

query {
  users(first: 1000000) {
    id
    name
    email
  }
}

推奨事項

GraphQL におけるオブジェクト制限のオーバーライドのリスクを緩和するには、以下の対策を実装します。

クエリの複雑さの分析: ツールまたはライブラリを使用して、受信クエリの複雑さを分析し、制限します。graphql-query-complexity のようなライブラリが役立ちます。

レート制限: レート制限を実装して、特定の期間内に単一のユーザーまたは IP アドレスから送信できるクエリの数を制限します。

ページネーションと制限: 単一のクエリで返されるデータの量に制限を適用します。データの量を制御するためにページネーションが使用されていることを確認します。

Example Implementation:

const { ApolloServer, gql } = require('apollo-server');
const { getComplexity, simpleEstimator, fieldExtensionsEstimator } = require('graphql-query-complexity');
const { GraphQLObjectType, GraphQLInt, GraphQLString, GraphQLSchema } = require('graphql');

// Define your GraphQL schema
const typeDefs = gql`
  type Query {
    hello: String
    user(id: ID!): User
  }

  type User {
    id: ID!
    name: String
    age: Int
  }
`;

// Define your resolvers
const resolvers = {
  Query: {
    hello: () => 'Hello world!',
    user: (_, { id }) => ({
      id,
      name: 'John Doe',
      age: 30,
    }),
  },
};

// Create an Apollo Server instance with query complexity analysis
const server = new ApolloServer({
  typeDefs,
  resolvers,
  plugins: [
    {
      // This plugin computes the complexity of incoming queries
      requestDidStart: () => ({
        didResolveOperation({ request, document }) {
          const complexity = getComplexity({
            schema: server.schema,
            query: document,
            variables: request.variables,
            estimators: [
              fieldExtensionsEstimator(),
              simpleEstimator({ defaultComplexity: 1 }),
            ],
          });

          // Define a maximum complexity limit
          const maxComplexity = 100;

          // Check if the query complexity exceeds the maximum allowed
          if (complexity > maxComplexity) {
            throw new Error(`Query is too complex: ${complexity}. Maximum allowed complexity: ${maxComplexity}`);
          }
        },
      }),
    },
  ],
});

// Start the server
server.listen().then(({ url }) => {
  console.log(`🚀 Server ready at ${url}`);
});
from graphql import parse, execute, validate, GraphQLError
from graphql.language.visitor import visit, Visitor

class ComplexityVisitor(Visitor):
    def __init__(self):
        self.complexity = 0
        self.max_complexity = 100

    def enter_field(self, node, key, parent, path, ancestors):
        complexity = 1  # Base complexity for each field
        self.complexity += complexity
        if self.complexity > self.max_complexity:
            raise GraphQLError(f"Query complexity exceeds maximum allowed complexity of {self.max_complexity}")

def complexity_middleware(schema, query):
    document = parse(query)
    visitor = ComplexityVisitor()
    visit(document, visitor)
    return visitor.complexity

def execute_with_complexity_check(schema, query, variables=None):
    complexity = complexity_middleware(schema, query)
    if complexity > 100:
        raise GraphQLError(f"Query complexity exceeds maximum allowed complexity of 100")
    result = execute(schema, parse(query), variable_values=variables)
    return result

By using these recommendations and configurations, you can better protect your GraphQL APIs from the risks associated with object limit overriding.

リンク

標準

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