Share on
·

How threat actors fingerprint your GraphQL APIs

Shahar Binyamin & Inigo team·

In previous blog posts, we discussed what’s involved in the process of detecting GraphQL servers. Threat actors don’t stop there, the identification of a target is only the initial step in the process of achieving the greater goal of compromising a GraphQL API target.

You’ve identified a GraphQL server, now what? Well, the next step in the process is to learn all you can about the specific server. You may be asking yourself, aren’t all GraphQL servers the same; they just provide an API layer to some application? While this is true, the first thing you should know is that there are many GraphQL server implementations, not all of them are mature, and not all of them are well maintained.

Let’s explore some of the GraphQL servers that are out there today. A good source for this is the https://graphql.org/code website, which lists client libraries, servers, tools as well services by the language they were written in. For this post, we’re going to focus only on server implementations. Below chart illustrates the number of GraphQL server implementations available today by language. You can find the detailed table at the bottom of this post.

GraphQL Servers Breakdown.png

As you can see, there are many different server implementations. Most notable are PHP (22.8%) Golang (12.3%) JavaScript (10.5%) Java (8.8%) and Python (7%).

Why is this important? When threat actors target an application or server, they need to gather a few key data points to increase their chances of successfully breaking in:

  1. What platform is running?
  2. Is the source code available?
  3. What version is it on?
  4. Are there any known vulnerabilities for it?
  5. Are there any available exploits for the vulnerabilities?
  6. What security features are built into it?
  7. Are there any insecure settings shipped by default?

To be able to know the answer to these questions, you first need to fingerprint the target. But how do you fingerprint an API? Since GraphQL is just an API layer, you may be asking yourself: how would someone know what GraphQL implementation it is if they should all conform with the specification and return the same predictable response structure? Well, if you craft a careful enough payload that the server does not expect, all it will take is a small and subtle difference in the response to distinguish one server from another. Let’s explore what this looks like.

GraphQL Server Fingerprint.png

GraphQL supports three operation types: query, mutation and subscription as described in section 2.3 Operations in the GraphQL specification. What would happen if an operation that doesn’t exist is provided, and what would the server respond with? Let’s find out:

queryyy { # notice the typo
   __typename
}

Using curl, we will send this malformed query to an Apollo-based GraphQL server

$ curl -s -X POST http://apollo.example.local -H "Content-Type: application/json" -d '{"query":"queryyy { __typename }"}' | jq

{
  "errors": [
    {
      "message": "Syntax Error: Unexpected Name \"queryyy\".",
      "extensions": {
        "code": "GRAPHQL_PARSE_FAILED"
      }
    }
  ]
}

So, we have an errors key with a message of Syntax Error: Unexpected Name "queryyy". Now, let’s do the same against a Graphene-based GraphQL server, a Python-based implementation.

$ curl -s -X POST http://graphene.example.local -H "Content-Type: application/json" -d '{"query":"queryyy { __typename }"}' | jq

{
  "errors": [
    {
      "message": "Syntax Error GraphQL (1:1) Unexpected Name \"queryyy\"
\n1: queryyy { __typename }\n   ^\n",
      "locations": [
        {
          "line": 1,
          "column": 1
        }
      ]
    }
  ]
}

Now we see that the error message is a little different. For example, instead of Syntax Error we now get Syntax Error GraphQL in the error message. This is an obvious difference that can help us pinpoint the implementation.

Tools that perform GraphQL fingerprinting surfaced over the years, such as Graphw00f that make use of these subtle differences to arm ethical hackers with the necessary knowledge and give them the ability to perform more educated guesses during penetration tests.

We mentioned earlier that some implementations are more mature than others, and offer protections that others don’t. In future posts, we will cover various vulnerabilities of different implementations. Whether you are using a popular GraphQL server implementation, or completely wrote your own custom implementation, Inigo abstracts your GraphQL API layer and provides security protections so you don’t need to worry about securing your GraphQL server, we do that for you.

List of GraphQL server implementations available as of this writing

# Implementation Language URL
1 graphql-js JavaScript https://graphql.org/graphql-js/
2 apollo JavaScript https://github.com/apollographql/apollo-server
3 graphql-yoga JavaScript https://github.com/dotansimha/graphql-yoga
4 express-graphql JavaScript https://github.com/graphql/express-graphql
5 mercurius JavaScript https://github.com/mercurius-js/mercurius
6 graphql-helix JavaScript https://github.com/contra/graphql-helix
7 graphql-go Golang https://github.com/graphql-go/graphql
8 gqlgen Golang https://github.com/99designs/gqlgen
9 graphql-go (graph-gophers) Golang https://github.com/graph-gophers/graphql-go
10 thunder Golang https://github.com/samsarahq/thunder
11 graphql-relay-go Golang https://github.com/graphql-go/relay
12 jaal Golang https://github.com/appointy/jaal
13 eggql Golang https://github.com/andrewwphillips/eggql
14 api-platform PHP https://api-platform.com/
15 graphql-php PHP https://github.com/webonyx/graphql-php
16 WPGraphQL PHP https://github.com/wp-graphql/wp-graphql
17 Lighthouse PHP https://github.com/nuwave/lighthouse
18 Siler PHP https://github.com/leocavalcante/siler
19 GraphQLBundle PHP https://github.com/overblog/GraphQLBundle
20 GraphQLite PHP https://github.com/thecodingmachine/graphqlite
21 Ralit PHP https://github.com/railt/railt
22 graphql-relay-php PHP https://github.com/ivome/graphql-relay-php
23 GraphQL by PoP PHP https://github.com/leoloso/PoP
24 GraphQL API for WordPress PHP https://github.com/leoloso/PoP
25 GraPHPinator PHP https://github.com/infinityloop-dev/graphpinator
26 serge PHP https://github.com/kepawni/serge
27 graphql-java Java https://github.com/graphql-java/graphql-java
28 Domain Graph Service (DGS) Framework Java https://github.com/netflix/dgs-framework
29 graphql-kotlin Java https://github.com/ExpediaGroup/graphql-kotlin
30 GraphQL Spring Boot Java https://github.com/graphql-java-kickstart/graphql-spring-boot
31 KGraphQL Java https://github.com/aPureBase/KGraphQL
32 graphql-dotnet C# / .NET https://github.com/graphql-dotnet/graphql-dotnet
33 Hot Chocolate C# / .NET https://github.com/ChilliCream/hotchocolate
34 NGraphQL C# / .NET https://github.com/rivantsov/ngraphql
35 Graphene Python https://github.com/graphql-python/graphene
36 Strawberry Python https://github.com/strawberry-graphql/strawberry
37 Ariadne Python https://github.com/mirumee/ariadne
38 Tartiflette Python https://github.com/tartiflette/tartiflette
39 Graphiti Swift https://github.com/GraphQLSwift/Graphiti
40 GraphZahl Swift https://github.com/nerdsupremacist/GraphZahl
41 Juniper Rust https://github.com/graphql-rust/juniper
42 Async-graphql Rust https://github.com/async-graphql/async-graphql
43 graphql-ruby Ruby https://github.com/rmosolgo/graphql-ruby
44 Agoo Ruby https://github.com/ohler55/agoo
45 Absinthe Elixir https://github.com/absinthe-graphql/absinthe
46 graphql-elixir Elixir https://github.com/graphql-elixir/graphql
47 Sangria Scala https://github.com/sangria-graphql/sangria
48 Caliban Scala https://github.com/ghostdogpr/caliban
49 Iacinia Clojure https://github.com/walmartlabs/lacinia
50 graphql-cli Clojure https://github.com/tendant/graphql-clj
51 alumbra Clojure https://github.com/alumbra/alumbra
52 Morpheus GraphQL Haskell https://github.com/morpheusgraphql/morpheus-graphql
53 Mu-Haskell Haskell https://github.com/higherkindness/mu-haskell
54 ocaml-graphql-server OCaml https://github.com/andreas/ocaml-graphql-server
55 graphql-erlang Erlang https://github.com/jlouis/graphql-erlang
56 ghql R https://github.com/ropensci/ghql
57 gorm-graphql Groovy https://github.com/grails/gorm-graphql
58 graphql-perl Perl https://github.com/graphql-perl/graphql-perl
59 graphqld D https://github.com/burner/graphqld
Ready to accelerate your GraphQL adoption?
Start Inigo for free
*No credit card needed
Join our newsletter