Built-in ID scalar used in output instead of a custom scalar
Issue ID: graphql-data-output-custom-scalar-id-needed
Average severity: Critical
Description
.The schema exposes identifiers using a built-in scalar of the type ID instead of using a domain-specific custom scalar.
For more details, see the GraphQL specification.
Possible exploit scenario
In GraphQL, the built-in ID scalar is defined as a unique identifier serialized as a string. However, this poses several problems:
- It accepts any string or integer value
- It has no format or length constraints
- It carries no semantic meaning
- It does not express ownership, tenant scope, or domain boundaries
- It does not enforce structural validation
Identifiers returned by an API are security-sensitive because:
- They define object-level access targets
- They enable subsequent mutation or query operations
- They allow enumeration of resources
- They reveal correlation patterns across systems
- They may expose internal database keys or predictable sequences
If a generic ID is used for all entity types, clients cannot distinguish between them. This increases the risk of:
- Type confusion between identifiers belonging to different domains
- Cross-entity misuse
- Broken Object Level Authorization (BOLA) exploitation
- Enumeration attacks when identifiers are sequential or predictable
- Leaking of internal database identifiers
In federated GraphQL architectures, this risk increases further: identifiers propagate across subgraphs, and type ambiguity may enable cross-service inconsistencies.
Using domain-specific custom scalars makes identifier semantics explicit and allows enforcing UUID-only formats, length restrictions, prefix or namespace rules, and strongly separated identifier domains. Because identifiers define the primary object-access boundary in GraphQL APIs, misuse or weak modeling of identifiers significantly increases the risk of their exploitation.
Remediation
Replace the built-in ID scalar with a domain-specific custom scalar that carries explicit constraints. We recommend that you:
- Define a distinct scalar for each identifier domain, such as:
UserIdAccountIdOrderIdTenantId
- Avoid exposing raw database keys
- Prefer opaque identifiers when possible
- Enforce strict format and length constraints
Explicit identifier modeling reduces enumeration risk, prevents cross-domain confusion, and improves the robustness of authorization.