AgentSkillsCN

Graphql Introspection

GraphQL 内省

SKILL.md

GraphQL Introspection Skill

Purpose

Performs GraphQL introspection queries to discover schema, types, queries, mutations, and subscriptions. Assesses schema completeness and identifies security concerns.

Detection Strategy

Step 1: Identify GraphQL Endpoint

Test these paths with a POST request:

PathNotes
/graphqlMost common
/gqlShort form
/api/graphqlNamespaced
/v1/graphqlVersioned
/graphql/v1Alt versioned
/queryHasura style

Step 2: Test Introspection

Send the introspection query:

graphql
{
  __schema {
    queryType { name }
    mutationType { name }
    subscriptionType { name }
    types {
      name
      kind
      description
      fields {
        name
        description
        type {
          name
          kind
          ofType {
            name
            kind
          }
        }
        args {
          name
          type {
            name
            kind
          }
        }
      }
    }
    directives {
      name
      description
    }
  }
}

HTTP Request:

code
POST /graphql HTTP/1.1
Content-Type: application/json

{
  "query": "{ __schema { queryType { name } mutationType { name } subscriptionType { name } types { name kind description fields { name description type { name kind ofType { name kind } } args { name type { name kind } } } } directives { name description } } }"
}

Step 3: Parse Schema

Extract the following from introspection results:

json
{
  "has_graphql_schema": true,
  "introspection_enabled": true,
  "endpoint": "/graphql",
  "schema": {
    "queries": [
      {
        "name": "getPayment",
        "args": ["id: ID!"],
        "return_type": "Payment"
      },
      {
        "name": "listPayments",
        "args": ["limit: Int", "offset: Int"],
        "return_type": "[Payment]"
      }
    ],
    "mutations": [
      {
        "name": "createPayment",
        "args": ["input: PaymentInput!"],
        "return_type": "Payment"
      }
    ],
    "subscriptions": [
      {
        "name": "onPaymentStatusChange",
        "args": ["paymentId: ID!"],
        "return_type": "PaymentEvent"
      }
    ],
    "types": {
      "custom": 25,
      "input": 10,
      "enum": 5,
      "interface": 2,
      "union": 1
    },
    "total_fields": 150,
    "total_queries": 15,
    "total_mutations": 8,
    "total_subscriptions": 3
  }
}

Security Assessment

Introspection Enabled (Security Risk)

If introspection is enabled in production:

json
{
  "security_concerns": [
    {
      "severity": "medium",
      "issue": "GraphQL introspection enabled in production",
      "description": "Introspection exposes the complete API schema including all types, queries, and mutations. This can aid attackers in understanding the API surface.",
      "recommendation": "Disable introspection in production. Use schema documentation tools instead."
    }
  ]
}

Other Security Checks

CheckRiskDescription
Introspection enabledMediumSchema exposure
No query depth limitHighDoS via nested queries
No query complexity limitHighResource exhaustion
Mutations without authCriticalUnauthorized data modification
PII in type namesLowInformation disclosure

Schema Analysis

Type Classification

Filter out built-in GraphQL types:

python
BUILTIN_TYPES = {"String", "Int", "Float", "Boolean", "ID",
                  "__Schema", "__Type", "__Field", "__InputValue",
                  "__EnumValue", "__Directive", "__DirectiveLocation"}

custom_types = [t for t in types if t["name"] not in BUILTIN_TYPES
                and not t["name"].startswith("__")]

Complexity Score

python
def schema_complexity(schema):
    types = len(schema["types"]["custom"])
    queries = schema["total_queries"]
    mutations = schema["total_mutations"]
    fields = schema["total_fields"]

    if fields > 500 or types > 100:
        return "high"
    elif fields > 100 or types > 30:
        return "medium"
    return "low"

Output Format

json
{
  "has_graphql_schema": true,
  "introspection_enabled": true,
  "endpoint": "https://api.example.com/graphql",
  "schema_summary": {
    "total_queries": 15,
    "total_mutations": 8,
    "total_subscriptions": 3,
    "custom_types": 25,
    "total_fields": 150,
    "complexity": "medium"
  },
  "security_concerns": [],
  "top_queries": ["getPayment", "listPayments", "getAccount"],
  "top_mutations": ["createPayment", "updatePayment"]
}