Security Cannot Be an Afterthought in Your DevOps Pipeline: Take GraphQL API as an Example

GraphQL API is a popular alternative to the traditional RESTful API framework:

GraphQL APIs - the new, Facebook-developed, GraphQL standard provides database access over a single POST endpoint (typically /graphql). It solves a common RESTful API problem – that of requiring multiple calls to populate a single UI page – while introducing other additional problems.

Imagine your devops team quickly jump to the challenge and constructed an autoscaling GraphQL API endpoint, which can handle millions of transactions per minute:

https://cool.example.com/graphql

It sounds cool and cloud-native, yet without paying due consideration to security, the autoscaling is merely spreading some inherent vulnerabilities to a wider set of nodes.

Let’s do a quick security audit, according to OWASP, a common configuration mistake is to leave the GraphQL introspection functionality open on the production hostname:

GraphQL introspection is a powerful functionality that can reply the full database schema to the enquirer, so powerful that every right-minded security professionals would agree it is better to turn it off in any production hostname.

You can use curl to do a quick check, here is an redacted example of a GraphQL hostname that the introspection function is left enabled inadvertently:

curl -H "accept: */*" -H "Content-Type: application/json" --data-binary '{"query":"\n query IntrospectionQuery {\r\n __schema {\r\n queryType { name }\r\n mutationType { name }\r\n subscriptionType { name }\r\n types {\r\n ...FullType\r\n }\r\n directives {\r\n name\r\n description\r\n locations\r\n args {\r\n ...InputValue\r\n }\r\n }\r\n }\r\n }\r\n\r\n fragment FullType on __Type {\r\n kind\r\n name\r\n description\r\n fields(includeDeprecated: true) {\r\n name\r\n description\r\n args {\r\n ...InputValue\r\n }\r\n type {\r\n ...TypeRef\r\n }\r\n isDeprecated\r\n deprecationReason\r\n }\r\n inputFields {\r\n ...InputValue\r\n }\r\n interfaces {\r\n ...TypeRef\r\n }\r\n enumValues(includeDeprecated: true) {\r\n name\r\n description\r\n isDeprecated\r\n deprecationReason\r\n }\r\n possibleTypes {\r\n ...TypeRef\r\n }\r\n }\r\n\r\n fragment InputValue on __InputValue {\r\n name\r\n description\r\n type { ...TypeRef }\r\n defaultValue\r\n }\r\n\r\n fragment TypeRef on __Type {\r\n kind\r\n name\r\n ofType {\r\n kind\r\n name\r\n ofType {\r\n kind\r\n name\r\n ofType {\r\n kind\r\n name\r\n ofType {\r\n kind\r\n name\r\n ofType {\r\n kind\r\n name\r\n ofType {\r\n kind\r\n name\r\n ofType {\r\n kind\r\n name\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n ","variables":null}' --compressed "https://cool.example.com/graphql"

The output is a big JSON and you can redirect it to visualization tool such as

For easier viewing:

Revealing sensitive payment related schema structures, extremely useful to an attacker attempting to penetrate your API.

Never treat security as an afterthought, as a healthy starter, go through OWASP cheat sheet to ensure your GraphQL API endpoints are not exposing common loopholes:

3 Likes