diff --git a/README.md b/README.md index ca7a5c6..1cc45d9 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,7 @@ graphw00f currently attempts to discover the following GraphQL engines: * Dgraph - JavaScript * Directus - TypeScript * AWS AppSync +* GraphQL Yoga - TypeScript # GraphQL Technologies Defence Matrices Each fingerprinted technology (e.g. Graphene, Ariadne, ...) has an associated document ([example for graphene](https://github.com/dolevf/graphw00f/blob/main/docs/graphene.md)) which covers the security defence mechanisms the specific technology supports to give a better idea how the implementation may be attacked. diff --git a/docs/graphql-yoga.md b/docs/graphql-yoga.md new file mode 100644 index 0000000..0177ea6 --- /dev/null +++ b/docs/graphql-yoga.md @@ -0,0 +1,16 @@ +# GraphQL Yoga + +# Table of Contents +* [About](#About) +* [Security Features](#Security-Features) + +# About +GraphQL Yoga is a fully-featured GraphQL Server with focus on easy setup, performance & great developer experience + +# Security Features +GraphQL Yoga offers the following security features: +``` +| Field Suggestions | Query Depth Limit | Query Cost Analysis | Automatic Persisted Queries | Introspection | Debug Mode | Batch Requests | +|-------------------|-------------------|---------------------|-----------------------------|----------------|----------------|-----------------| +| On by Default | Off by Default | No Support | No Support | Off by Default | Off by Default | Off by Default | +``` diff --git a/graphw00f/helpers.py b/graphw00f/helpers.py index d39d6b4..25abf81 100644 --- a/graphw00f/helpers.py +++ b/graphw00f/helpers.py @@ -192,6 +192,12 @@ def get_engines(): 'url':'https://directus.io/', 'ref':'https://github.com/dolevf/graphw00f/blob/main/docs/directus.md', 'technology':['TypeScript'] + }, + 'graphql_yoga':{ + 'name':'GraphQL Yoga', + 'url':'https://github.com/dotansimha/graphql-yoga', + 'ref':'https://github.com/dolevf/graphw00f/blob/main/docs/graphql-yoga.md', + 'technology':['TypeScript'] } } diff --git a/graphw00f/lib.py b/graphw00f/lib.py index 59306a1..6ef1f23 100644 --- a/graphw00f/lib.py +++ b/graphw00f/lib.py @@ -39,7 +39,9 @@ def check(self, url): def execute(self, url): self.url = url - if self.engine_dgraph(): + if self.engine_graphql_yoga(): + return 'graphql_yoga' + elif self.engine_dgraph(): return 'dgraph' elif self.engine_graphene(): return 'graphene' @@ -95,7 +97,19 @@ def graph_query(self, url, operation='query', payload={}): return response.json() except: return {} + + def engine_graphql_yoga(self): + query = ''' + subscription { + __typename + } + ''' + response = self.graph_query(self.url, payload=query) + print(response) + if error_contains(response, 'asyncExecutionResult[Symbol.asyncIterator] is not a function') or error_contains(response, 'Unexpected error.'): + return True + return False def engine_apollo(self): query = ''' query @skip { @@ -528,8 +542,9 @@ def engine_dgraph(self): } ''' response = self.graph_query(self.url, payload=query) - if response.get('data', {}).get('__typename', '') == 'Query': - return True + if 'data' in response and response['data']: + if response.get('data').get('__typename', '') == 'Query': + return True query = ''' query {