shuvonsec/graphql-idor-scanner: The Differential Engine for GraphQL Identity Theft

Moving beyond status codes to detect cross-tenant data leakage through automated session comparison.

• View on GitHub • More from shuvonsec

An illustration of a large, heavily guarded main gate next to a small, completely unmonitored utility door, representing the contrast between secured specific queries and vulnerable generic node fetchers in API security.
While the front door is locked, the utility entrance often remains wide open.

Key Takeaways

In the transition from REST to GraphQL, developers traded predictable, hierarchical URL paths for a "Global ID" black box. This architectural shift broke a fundamental assumption of traditional security scanning: that an unauthorized request would neatly return an HTTP 403 Forbidden or a 404 Not Found.

Modern APIs, particularly those employing GraphQL, often return a HTTP 200 OK even when an error occurs, burying the authorization failure deep within a JSON payload. Or worse, they return the requested data without checking who asked for it. This is the domain of the Insecure Direct Object Reference (IDOR), a vulnerability where an application fails to properly verify if the user requesting a resource is actually authorized to view it.

Generic infrastructure scanners are notoriously bad at finding these logic flaws because they lack context. They look for signature matches and status codes. The graphql-idor-scanner takes a different approach. It doesn't care if a request is syntactically valid or what HTTP status code is returned. It only cares about one thing: if the data returned to a stranger matches the data owned by the victim.

The Node IDOR: GraphQL’s Universal Backdoor

To understand why this tool exists, you have to understand the Relay specification and the concept of the Global ID (GID). In many complex GraphQL schemas, objects can be fetched via a generic node(id: ID!) interface. This is incredibly useful for client-side caching, allowing frameworks to request any object if they know its GID.

However, this creates a significant security blind spot. Developers often meticulously secure the specific queries—ensuring that query { invoice(id: 123) { amount } } checks if the user owns invoice 123. But they frequently forget to apply the same authorization logic to the generic node fetcher.

query {
  node(id: "Z2lkOi8vYXBwL0ludm9pY2UvMTIz") {
    ... on Invoice {
      amount
      customerName
    }
  }
}

If the underlying resolver for the Invoice type doesn't independently verify ownership, an attacker can bypass the secured front door and simply ask the generic node query for the sensitive data. graphql-idor-scanner specifically targets this pattern. It automates the generation and manipulation of these Base64-encoded GIDs (like the one in the snippet above, which decodes to gid://app/Invoice/123) to systematically test for "Node IDORs."

How Global IDs are constructed and hijacked.

Differential Analysis: The "Two-Key" System

The core innovation of the scanner is its dual-session architecture. It requires two distinct authentication tokens: Token A (belonging to the victim or resource owner) and Token B (belonging to the attacker). The script relies on a concept called differential analysis.

  1. Baseline Establishment: The scanner first executes a request using Token A to ensure the target resource is actually accessible and the query is well-formed.
  2. Unauthorized Replay: It then executes the exact same request, targeting the same resource ID, but using Token B.
  3. Data Comparison: The script compares the JSON response bodies. If Account B receives a populated data object that matches Account A's response—and no errors are present—the vulnerability is confirmed.

This method effectively eliminates the noise associated with traditional scanning. A 403 Forbidden is a "secure" state. A null response with an error message is a "secure" state. The scanner only flags a hit when the "mirror test" fails—when the attacker sees the exact same reflection as the victim.

An illustration of two identical mirrors facing each other. One reflects a person's face, while the other reflects a stranger but shows the first person's reflection, symbolizing cross-tenant data leakage.
The differential logic engine only flags a vulnerability when the attacker's view matches the victim's.

Zero Dependencies, Maximum Portability

In an era of massive, containerized security suites, graphql-idor-scanner stands out for its austerity. It requires exactly zero external dependencies, relying entirely on the Python 3.10+ Standard Library. It uses urllib.request for network calls and the built-in json module for parsing.

This "Standard Library Only" philosophy makes the tool exceptionally portable. It is a utility designed for ephemeral environments—a locked-down VPS, a quick terminal session during a bug bounty engagement, or a CI/CD pipeline where installing third-party packages is restricted. It trades the exhaustive feature set of enterprise scanners for immediate, frictionless execution.

Bridging the Protocol Gap

Interestingly, the tool doesn't restrict itself purely to GraphQL. The author recognizes that modern applications often maintain a "shadow" REST API alongside their GraphQL implementation, exposing the same underlying data layers.

Among its 13 predefined test modules, the scanner includes checks for REST-based search index leakage and S3 Signed URL validation. This holistic approach acknowledges that if you can bypass authorization via a legacy REST endpoint, the meticulous security applied to the GraphQL schema is effectively moot.

Featuregraphql-idor-scannerGeneric Infrastructure ScannersIntrospection Fuzzers
Primary TargetBusiness Logic / AuthorizationKnown CVEs / MisconfigurationsDenial of Service / Query Depth
Detection MethodDifferential Data ComparisonSignature Matching / HTTP CodesPayload Generation
Setup ComplexityLow (Zero dependencies)High (Requires installation/config)Medium (Requires schema parsing)
False Positive RateExtremely LowHigh (Flags intended 403s)High (Flags generic errors)

By focusing narrowly on the logic of authorization rather than the mechanics of the protocol, graphql-idor-scanner provides a high-signal, low-noise approach to finding one of the most persistent and damaging vulnerabilities in modern web architecture.