Skip to content

Commit

Permalink
Merge branch 'main' of github.com:azuax/graphw00f
Browse files Browse the repository at this point in the history
  • Loading branch information
azuax committed Sep 30, 2024
2 parents 7840dd8 + 701e4c1 commit afb7606
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 8 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ graphw00f currently attempts to discover the following GraphQL engines:
* GraphQL.NET - Microsoft .NET
* pg_graphql - Rust
* tailcall - Rust
* Hot Chocolate - Microsoft .NET

# GraphQL Threat Matrix
The graphw00f project uses the [GraphQL Threat Matrix Project](https://github.com/nicholasaleks/graphql-threat-matrix/) as its technology security matrix database. When graphw00f successfully fingerprints a GraphQL endpoint, it will print out the threat matrix document. This document helps security engineers to identify how mature the technology is, what security features it offers, and whether it contains any CVEs.
Expand Down
28 changes: 22 additions & 6 deletions graphw00f/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,19 @@ def read_custom_wordlist(location):
return wordlists

def error_contains(response, word_to_match, part='message'):
if isinstance(response, dict):
if response.get('errors'):
for i in response['errors']:
err_message = i.get(part, '')
if word_to_match in err_message:
return True
word_to_match = word_to_match.lower()

if isinstance(response, dict):
errors = response.get('errors', [])
if isinstance(errors, list):
return any(
word_to_match in (error.get(part, '') if isinstance(error, dict) else str(error)).lower()
for error in errors
)
elif isinstance(errors, str):
return word_to_match in errors.lower()
elif isinstance(response, str):
return word_to_match in response.lower()
return False

def get_time():
Expand Down Expand Up @@ -71,6 +78,9 @@ def possible_graphql_paths():
'/v1/graphiql',
'/v2/graphiql',
'/v3/graphiql',
'/graphql/v1',
'/graphql/v2',
'/graphql/v3',
'/api/graphql',
'/api/graphiql',
'/console',
Expand Down Expand Up @@ -280,6 +290,12 @@ def get_engines():
'url':'https://tailcall.run',
'ref':'https://github.com/nicholasaleks/graphql-threat-matrix/blob/master/implementations/tailcall.md',
'technology':['Rust']
},
'hotchocolate':{
'name':'hotchocolate',
'url':'https://chillicream.com/docs/hotchocolate/v13',
'ref':'https://github.com/nicholasaleks/graphql-threat-matrix/blob/master/implementations/hotchocolate.md',
'technology':['C#', '.NET']
}
}

Expand Down
25 changes: 24 additions & 1 deletion graphw00f/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def check(self, url):
if response.get('data'):
if response.get('data', {}).get('__typename', '') in ('Query', 'QueryRoot', 'query_root'):
return True
elif response.get('errors') and (any('locations' in i for i in response['errors']) or (any('extensions' in i for i in response))):
elif response.get('errors') and (any('locations' in i for i in response['errors']) or any('extensions' in i for i in response['errors'])):
return True
elif response.get('data'):
return True
Expand Down Expand Up @@ -109,6 +109,8 @@ def execute(self, url):
return 'graphql-dotnet'
elif self.engine_pggraphql():
return 'pg_graphql'
elif self.engine_hotchocolate():
return 'hotchocolate'

return None

Expand Down Expand Up @@ -724,4 +726,25 @@ def engine_pggraphql(self):
if error_contains(response, 'Unknown argument to @skip: aa'):
return True

return False

def engine_hotchocolate(self):
query = '''
queryy {
__typename
}
'''
response = self.graph_query(self.url, payload=query)
if error_contains(response, 'Unexpected token: Name.'):
return True

query = '''
query @aaa@aaa {
__typename
}
'''
response = self.graph_query(self.url, payload=query)
if error_contains(response, 'The specified directive `aaa` is not supported by the current schema.'):
return True

return False
2 changes: 1 addition & 1 deletion version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
VERSION = '1.1.16'
VERSION = '1.1.18'

0 comments on commit afb7606

Please sign in to comment.