Back to skills
SKILL.md
Sc Graphql
ASecurityGraphQL injection, introspection abuse, query complexity attacks, and authorization bypass detection
- 4 stars
- 0 votes
- 0 copies
- 2 views
- Added September 12, 2026
Works with
Security analysis
100/100Pro scans all 2 files and shows the line behind each finding
npx -y skills add aibot88/sec_skill_store --skill sc-graphql --agent claude-codeAre you the author of Sc Graphql?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/aibot88-sc-graphql)---
name: sc-graphql
description: GraphQL injection, introspection abuse, query complexity attacks, and authorization bypass detection
license: MIT
metadata:
category: security
version: "1.0.0"
---
# SC: GraphQL Security
## Purpose
Detects GraphQL-specific security vulnerabilities including query injection, introspection information disclosure, batching abuse, nested query denial-of-service, field-level authorization bypass, and subscription hijacking. Covers Apollo Server, graphql-yoga, Strawberry, Graphene, gqlgen, and HotChocolate.
## Activation
Called by sc-orchestrator during Phase 2 when GraphQL schema files, resolvers, or GraphQL dependencies are detected.
## Phase 1: Discovery
### File Patterns to Search
```
**/*.graphql, **/*.gql, **/schema.*, **/typeDefs.*, **/resolvers.*,
**/*resolver*, **/*schema*, **/*graphql*, **/mutations/*, **/queries/*,
**/subscriptions/*, **/directives/*
```
### Keyword Patterns to Search
```
"typeDefs", "resolvers", "ApolloServer", "graphql-yoga", "makeExecutableSchema",
"buildSchema", "@Query", "@Mutation", "@Resolver", "GraphQLObjectType",
"introspection", "depthLimit", "costAnalysis", "complexityLimit",
"__schema", "__type", "subscription", "directive"
```
### Security Checks
**1. Introspection Enabled in Production**
- Check if introspection is explicitly disabled in production config
- Search for: `introspection: true`, missing introspection config, `NODE_ENV` checks
**2. Query Depth/Complexity Limits Missing**
- Check for depth limiting middleware: `graphql-depth-limit`, `depthLimit`, `@complexity`
- Check for query cost analysis: `graphql-query-complexity`, `costAnalysis`
- Absence of both = vulnerable to nested query DoS
**3. Batching Without Limits**
- Check if query batching is enabled without limits
- Search for: `allowBatchedHttpRequests`, batch query handler, array query acceptance
**4. Field-Level Authorization**
- Check if resolver functions verify user permissions
- Search for missing auth checks in mutation resolvers
- Check directive-based auth: `@auth`, `@hasRole`, `@authenticated`
**5. SQL/NoSQL Injection in Resolvers**
- Trace GraphQL arguments through resolver to database queries
- Check if arguments are used in raw queries without parameterization
**6. Information Disclosure via Error Messages**
- Check if detailed error messages are returned to clients
- Search for: `formatError`, `debug: true`, stack trace exposure
**7. Subscription Authorization**
- Check WebSocket subscription handlers for auth validation
- Verify subscription filters don't leak data to unauthorized users
## Phase 2: Verification
### Nested Query DoS Example
```graphql
# Attack: Deeply nested query (no depth limit)
query {
user(id: 1) {
posts {
author {
posts {
author {
posts { # ...repeating to depth 50+
title
}
}
}
}
}
}
}
```
```javascript
// VULNERABLE: No depth or complexity limits
const server = new ApolloServer({
typeDefs,
resolvers,
});
// SAFE: With depth and complexity limits
import depthLimit from 'graphql-depth-limit';
import { createComplexityLimitRule } from 'graphql-validation-complexity';
const server = new ApolloServer({
typeDefs,
resolvers,
validationRules: [
depthLimit(10),
createComplexityLimitRule(1000),
],
introspection: process.env.NODE_ENV !== 'production',
});
```
### Authorization Bypass Example
```javascript
// VULNERABLE: No auth check in resolver
const resolvers = {
Mutation: {
deleteUser: async (_, { id }, context) => {
return await User.findByIdAndDelete(id); // Anyone can delete any user
}
}
};
// SAFE: Auth check in resolver
const resolvers = {
Mutation: {
deleteUser: async (_, { id }, context) => {
if (!context.user || context.user.role !== 'admin') {
throw new ForbiddenError('Not authorized');
}
return await User.findByIdAndDelete(id);
}
}
};
```
## Severity Classification
- **Critical:** SQL/NoSQL injection through GraphQL arguments, authentication bypass in mutations
- **High:** Missing field-level authorization on sensitive mutations, introspection enabled exposing internal schema in production
- **Medium:** Missing query depth/complexity limits (DoS risk), batching abuse, subscription data leaks
- **Low:** Verbose error messages, introspection enabled in staging, missing rate limiting on queries
## Output Format
### Finding: GQL-{NNN}
- **Title:** {GraphQL vulnerability type}
- **Severity:** Critical | High | Medium | Low
- **Confidence:** 0-100
- **File:** file/path:line
- **Vulnerability Type:** CWE-89 (Injection) | CWE-200 (Information Disclosure) | CWE-862 (Missing Authorization) | CWE-770 (Resource Exhaustion)
- **Description:** {What was found}
- **Proof of Concept:** {Example query demonstrating the issue}
- **Impact:** {What happens if exploited}
- **Remediation:** {How to fix with code example}
- **References:** https://cheatsheetseries.owasp.org/cheatsheets/GraphQL_Cheat_Sheet.html
## Common False Positives
1. **Introspection in development** — introspection is expected in dev/staging environments
2. **Public queries without auth** — some queries are intentionally public (e.g., product listings)
3. **Depth limits in gateway** — depth limiting may be enforced at the API gateway level, not in the GraphQL server
4. **Schema-first codegen** — generated resolvers may appear to lack auth but are wrapped by middleware
5. **Federated schemas** — auth may be handled by the gateway in a federated GraphQL architecture
Files in this skill
- SKILL.md
- source.json
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.