Skip to main content
ESLint Interlace
Plugin: secure-codingRules

no-graphql-injection

Detects GraphQL injection vulnerabilities and DoS attacks

Keywords: GraphQL injection, CWE-943, CWE-400, security, DoS, introspection, query complexity, LLM-optimized

CWE: CWE-74
OWASP Mobile: OWASP Mobile Top 10

Detects GraphQL injection vulnerabilities and DoS attacks. This rule is part of eslint-plugin-secure-coding and provides LLM-optimized error messages.

πŸ’Ό This rule is set to error in the recommended config.

Quick Summary

AspectDetails
CWE ReferenceCWE-943 (GraphQL Injection), CWE-400 (DoS)
SeverityCritical
Auto-FixπŸ’‘ Suggestions available
CategorySecurity

Value & investment case

Why this rule pays for itself. Framework: cicd-impact/philosophy.md.

DimensionValue
CWECWE-943 β€” Improper Neutralization in Data Query Logic + CWE-400 (DoS)
Feedback-loop tierEditor / pre-commit (sub-second) β€” cheapest layer per the feedback-loop hierarchy
Defensive-layer leverage~10Γ— cheaper than unit-test Β· ~1,000Γ— cheaper than production rollback Β· 10,000+Γ— cheaper than customer disclosure (cost-ratio anchors)
Niche relevanceCritical: B2B SaaS (GraphQL-heavy modern API surface), fintech Β· High: marketplaces, infra/devtools, healthtech Β· Medium: B2C
Investor-frame impactGraphQL injection β†’ unauthorized data access across multiple tenants in a B2B SaaS = single-incident multi-customer disclosure cycle. Catch at lint-time prevents the breach class entirely.

Read also: philosophy.md Β§investor-frame Β· niche-presets.json Β· analyzer-evaluation-framework.md

Vulnerability and Risk

Vulnerability: GraphQL injection arises when backend queries are constructed dynamically using user inputs via string concatenation or interpolation, instead of using standard GraphQL variables.

Risk: Attackers can manipulate the query structure to bypass permissions, access unauthorized data fields, perform Denial of Service (DoS) via nested queries, or execute batching attacks to overload the server.

Rule Details

GraphQL injection occurs when user input is improperly inserted into GraphQL queries, allowing attackers to:

  • Read or modify unauthorized data
  • Perform DoS attacks with complex/nested queries
  • Extract schema information via introspection

Why This Matters

IssueImpactSolution
πŸ”’ InjectionUnauthorized data accessUse GraphQL variables
πŸ”₯ DoSService unavailabilityLimit query depth/complexity
πŸ” Info LeakSchema exposureDisable introspection in production

Examples

❌ Incorrect

// String interpolation in GraphQL query
const query = `
  query {
    user(id: "${userId}") {
      name
      email
    }
  }
`;

// Introspection query in production
const introspect = `{ __schema { types { name } } }`;

// String concatenation
const searchQuery = 'query { users(name: "' + userInput + '") { id } }';

βœ… Correct

// Use GraphQL variables
const query = gql`
  query GetUser($userId: ID!) {
    user(id: $userId) {
      name
      email
    }
  }
`;
await client.query({ query, variables: { userId } });

// Use query builders
import { buildQuery } from 'graphql-tools';
const safeQuery = buildQuery({ user: { id: userId } });

Configuration

{
  rules: {
    'secure-coding/no-graphql-injection': ['error', {
      allowIntrospection: false,       // Disable introspection detection
      maxQueryDepth: 10,               // Maximum query nesting depth
      trustedGraphqlLibraries: ['graphql', 'apollo-server', 'graphql-tools'],
      validationFunctions: ['validate', 'sanitize']
    }]
  }
}

Options

OptionTypeDefaultDescription
allowIntrospectionbooleanfalseAllow introspection queries
maxQueryDepthnumber10Maximum allowed query depth
trustedGraphqlLibrariesstring[]['graphql', 'apollo-server']Safe GraphQL libraries
validationFunctionsstring[]['validate', 'sanitize']Input validation functions

Error Message Format

πŸ”’ CWE-943 OWASP:A03-Injection CVSS:8.6 | GraphQL Injection detected | CRITICAL [SOC2,PCI-DSS]
   Fix: Use GraphQL variables instead of string interpolation | https://owasp.org/...

Known False Negatives

The following patterns are not detected due to static analysis limitations:

Query from Variable

Why: Query strings from variables not traced.

// ❌ NOT DETECTED - Query from variable
const query = `SELECT * FROM users WHERE id = ${userId}`;
db.execute(query);

Mitigation: Always use parameterized queries.

Custom Query Builders

Why: Custom ORM/query builders not recognized.

// ❌ NOT DETECTED - Custom builder
customQuery.where(userInput).execute();

Mitigation: Review all query builder patterns.

Template Engines

Why: Template-based queries not analyzed.

// ❌ NOT DETECTED - Template
executeTemplate('query.sql', { userId });

Mitigation: Validate all template variables.

Further Reading