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.
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:
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 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.
# | 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 |