SECURE_NODE // ATHENS_GR
← BACK TO RESEARCH Technique · API Security · GraphQL

Unauthenticated GraphQL Endpoint with Introspection Enabled

24 JUN 2026| ≈ 3 MIN READ| GraphQLBrokenAccessControlAPI SecurityRecon
SANITIZED ▸ Methodology only. All hostnames and paths are lab placeholders. No client name, real domain, or schema content appears here. Assessment was authorized and scoped in writing.

A CMS content delivery API exposed a GraphQL endpoint without authentication. Introspection was enabled by default, meaning any unauthenticated HTTP client could submit a schema query and receive a full map of every type, field, and relationship the backend exposes — including content objects, product categories, and customer segment structures. The same endpoint was present on two separate subdomains within scope, both returning schema without a session token.

What introspection gives an attacker

GraphQL introspection is a built-in feature that allows clients to query the schema itself. In a development or internal context this is useful. In a production API with no authentication gate, it hands a complete data model to any caller. The attacker doesn't guess field names, navigate documentation, or probe endpoints blind — the schema is delivered on request, structured and machine-readable, in a single query.

SEVERITY
Medium
schema + content exposure
COMPLEXITY
Low
single unauthenticated POST
KEY FLAW
No auth + introspection
default configuration, production

The request and what it returns

POST /graphql/endpoint.json HTTP/1.1
Host: content.retaillab.example.test
Content-Type: application/json

{"query":"{ __schema { types { name fields { name } } } }"}

# response: HTTP 200, full schema returned with no authentication
# types included: Product, Category, Banner, Page, PriceRule,
#                 CustomerSegment, PromotionGroup, ContentBlock ...
# introspection enabled in production — default configuration unchanged

Follow-up queries against the discovered types confirmed that content data was retrievable without authentication. Whether a given type returns published-only records or includes draft and unpublished content depends on query-level controls that are rarely tested independently — the introspection result alone is enough to know which types exist and how to query them.

Why this matters beyond the schema

The practical risk of an unauthenticated introspection endpoint is reconnaissance compression. An attacker who maps the schema in under a second can immediately write targeted queries against real data objects rather than spending time on blind enumeration. In a retail context the schema describes product pricing rules, promotion structures, and customer segmentation logic — the kind of business-sensitive content that the platform likely considers internal. The two-subdomain footprint also means patching one instance without auditing the other leaves an open path.

DAY 1 — DISCOVERY

CMS subdomain identified during scope mapping. GraphQL endpoint path found via directory enumeration on the content delivery subdomain.

DAY 1 — INTROSPECTION CONFIRMED

Introspection query returned full schema without credentials. Types, fields, and relationships enumerated. No authentication challenge issued.

DAY 1 — SECOND INSTANCE

Same endpoint confirmed on a second subdomain. Both return identical schema. Neither requires authentication. Two separate vulnerable instances within scope.

DAY 2 — REPORT

Both instances documented. Introspection evidence and follow-up data queries captured. Raised as a single finding with two vulnerable locations noted.

Fixing the exposure

  • Require a valid session token before processing any GraphQL request — introspection and data queries alike. The authentication gate must sit at the API layer, not rely on network-level controls that can be bypassed from within scope.
  • Disable introspection in production. Most GraphQL frameworks support this with a single configuration flag. Development and staging environments can retain it; production should not expose the schema to unauthenticated callers under any circumstance.
  • Define and enforce an allow-list of permitted query operations. Reject any query that references types or fields outside the allow-list, regardless of whether introspection is enabled. This limits the blast radius if introspection is re-enabled inadvertently.
  • Audit all subdomains and environments for the same endpoint path — a second instance was found within the same scope. Any deployment pipeline that provisions the CMS should enforce the authentication and introspection configuration as part of the provisioning step.

The takeaway

An unauthenticated GraphQL endpoint with introspection enabled is a reconnaissance shortcut that costs an attacker nothing. One POST request, one 200 response, and the full data model is mapped. The fix is a configuration change, not an architecture change — the exposure exists because a default was left in place, not because the design is fundamentally broken.