xclade
GraphQL API

Security

GraphQL API security features and protections

Security Features

The GraphQL API implements comprehensive security measures to protect against common vulnerabilities and attacks.

Rate Limiting

Protection: Prevents API abuse through request throttling
Default Limit: 100 requests per minute per client
Enforcement: Based on authenticated user ID or IP address
Storage: Redis-based for distributed systems, in-memory fallback for single instances

When rate limit is exceeded:

{
  "errors": [{
    "message": "Rate limit exceeded",
    "extensions": {
      "code": "RATE_LIMIT_EXCEEDED",
      "limit": 100,
      "windowMs": 60000,
      "retryAfter": 45
    }
  }]
}

Query Depth Limiting

Protection: Prevents deeply nested queries that could overwhelm the server
Default Limit: 10 levels deep
Scope: Applies to all field selections

Example of rejected query:

{
  "errors": [{
    "message": "Query depth limit exceeded. Maximum depth: 10, requested: 12",
    "extensions": {
      "code": "DEPTH_LIMIT_EXCEEDED",
      "maxDepth": 10,
      "actualDepth": 12
    }
  }]
}

Query Complexity Limiting

Protection: Prevents expensive queries based on complexity analysis
Default Limit: 1000 complexity points
Calculation: Each field adds complexity, lists multiply based on limit argument

Example:

{
  "errors": [{
    "message": "Query complexity limit exceeded. Maximum complexity: 1000, requested: 1250",
    "extensions": {
      "code": "COMPLEXITY_LIMIT_EXCEEDED",
      "maxComplexity": 1000,
      "actualComplexity": 1250
    }
  }]
}

Field Count Limiting

Protection: Prevents queries that request too many fields
Default Limit: 100 fields per query
Scope: Counts all selected fields across the entire query

Batch Query Protection

Protection: Prevents batching attacks where multiple operations are sent in a single request
Default Limit: 5 operations per request
Enforcement: Applied before query execution

Rejected batch request:

{
  "errors": [{
    "message": "Too many operations in batch. Maximum: 5, requested: 10",
    "extensions": {
      "code": "BATCH_LIMIT_EXCEEDED",
      "maxBatch": 5,
      "actualBatch": 10
    }
  }]
}

Request Size Limiting

Protection: Prevents DoS attacks through large payloads
Query Limit: 100KB maximum
Variables Limit: 50KB maximum

CSRF Protection

Protection: Prevents cross-site request forgery attacks
Requirement: Custom header required for mutations in production
Header: x-graphql-request: true

Without the required header:

{
  "errors": [{
    "message": "CSRF protection: Missing required header 'x-graphql-request' for mutations",
    "extensions": {
      "code": "CSRF_PROTECTION_FAILED",
      "requiredHeader": "x-graphql-request",
      "hint": "Add header 'x-graphql-request: true' to your GraphQL client"
    }
  }]
}

Schema Introspection Control

Protection: Prevents schema enumeration in production
Access: Admin users only in production, all users in development
Benefit: Reduces attack surface by hiding schema structure

GraphQL Armor Protection

Additional protections provided by GraphQL Armor:

  • Alias Limiting: Maximum 15 aliases per query (prevents alias flooding attacks)
  • Token Limiting: Maximum 1000 tokens per query (prevents huge query strings)
  • Directive Limiting: Maximum 50 directives per query (prevents directive abuse)
  • Cost Analysis: Advanced query cost calculation with 5000 point limit
  • Field Suggestion Blocking: Disables field name suggestions in production errors

Error Masking

Protection: Prevents information disclosure through error messages
Behavior: Internal errors are masked in production, detailed in development
Code Assignment: All errors include a standardized code in the extensions field

Production error example:

{
  "errors": [{
    "message": "Internal server error",
    "extensions": {
      "code": "INTERNAL_SERVER_ERROR"
    }
  }]
}

Query Timeout

Protection: Prevents long-running queries from consuming resources
Default Timeout: 10 seconds
Enforcement: Query execution is terminated if it exceeds the timeout

Authorization

All queries and mutations enforce proper authorization:

  • Authentication Required: Many queries require valid authentication
  • Role-Based Access: Admin-only operations are protected
  • Resource Ownership: Users can only access their own data (except admins)
  • Field-Level Security: Sensitive fields are conditionally available based on permissions

Example authorization error:

{
  "errors": [{
    "message": "Authentication required",
    "extensions": {
      "code": "UNAUTHENTICATED"
    }
  }]
}

On this page