Skip to content

Commit

Permalink
remove circular-fragment, add post-based csrf
Browse files Browse the repository at this point in the history
  • Loading branch information
dolevf committed Jun 20, 2022
1 parent 35f9e90 commit 1948851
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 60 deletions.
11 changes: 5 additions & 6 deletions graphql-cop.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
from lib.tests.dos_directive_overloading import directive_overloading
from lib.tests.info_trace_mode import trace_mode
from lib.tests.dos_circular_introspection import circular_query_introspection
from lib.tests.dos_circular_fragment import circular_fragment
from lib.tests.info_get_based_mutation import get_based_mutation
from lib.tests.info_post_based_csrf import post_based_csrf
from lib.utils import is_graphql, draw_art


Expand All @@ -31,6 +31,7 @@
help='Sends the request through http://127.0.0.1:8080 proxy')
parser.add_option('--version', '-v', dest='version', action='store_true', default=False,
help='Print out the current version and exit.')

options, args = parser.parse_args()

if options.version:
Expand Down Expand Up @@ -67,21 +68,19 @@
print(url, 'does not seem to be running GraphQL.')
sys.exit(1)

tests = [field_suggestions, introspection, detect_graphiql,
tests = [field_suggestions, introspection, detect_graphiql,
get_method_support, alias_overloading, batch_query,
field_duplication, trace_mode, directive_overloading,
circular_query_introspection, circular_fragment,
get_based_mutation]
circular_query_introspection, get_based_mutation, post_based_csrf]

json_output = []

for test in tests:
json_output.append(test(url, proxy, HEADERS))

if options.format == 'json':
print(json_output)
else:
for i in json_output:
if i['result']:
print('[{}] {} - {} ({})'.format(i['severity'], i['title'], i['description'], i['impact']))

41 changes: 0 additions & 41 deletions lib/tests/dos_circular_fragment.py

This file was deleted.

6 changes: 3 additions & 3 deletions lib/tests/info_get_based_mutation.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""Checks mutation support over on GET."""
from lib.utils import request_get, curlify
from lib.utils import request, curlify


def get_based_mutation(url, proxies, headers):
Expand All @@ -14,9 +14,9 @@ def get_based_mutation(url, proxies, headers):

q = 'mutation {__typename}'

response = request_get(url, proxies=proxies, headers=headers, params={'query':q})
response = request(url, proxies=proxies, headers=headers, params={'query':q})
res['curl_verify'] = curlify(response)

try:
if response and response.json()['data']['__typename']:
res['result'] = True
Expand Down
8 changes: 4 additions & 4 deletions lib/tests/info_get_method_support.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""Collect all supported methods."""
from lib.utils import request_get, curlify
from lib.utils import request, curlify


def get_method_support(url, proxies, headers):
Expand All @@ -9,15 +9,15 @@ def get_method_support(url, proxies, headers):
'title':'GET Method Query Support',
'description':'GraphQL queries allowed using the GET method',
'impact':'Possible Cross Site Request Forgery (CSRF)',
'severity':'LOW',
'severity':'MEDIUM',
'curl_verify':''
}

q = '{__typename}'

response = request_get(url, proxies=proxies, headers=headers, params={'query':q})
response = request(url, proxies=proxies, headers=headers, params={'query':q})
res['curl_verify'] = curlify(response)

try:
if response and response.json()['data']['__typename']:
res['result'] = True
Expand Down
4 changes: 2 additions & 2 deletions lib/tests/info_graphiql.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Collect GraphiQL details."""
from urllib.parse import urlparse
from lib.utils import request_get, curlify
from lib.utils import request, curlify


def detect_graphiql(url, proxy, headers):
Expand All @@ -21,7 +21,7 @@ def detect_graphiql(url, proxy, headers):
url = '{}://{}'.format(parsed.scheme, parsed.netloc)

for endpoint in endpoints:
response = request_get(url + endpoint, proxies=proxy, headers=headers)
response = request(url + endpoint, proxies=proxy, headers=headers)
res['curl_verify'] = curlify(response)
try:
if response and any(word in response.text for word in heuristics):
Expand Down
26 changes: 26 additions & 0 deletions lib/tests/info_post_based_csrf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"""Checks if queries are allowed over POST not in JSON."""
from lib.utils import request, curlify


def post_based_csrf(url, proxies, headers):
res = {
'result':False,
'title':'POST based url-encoded query (possible CSRF)',
'description':'GraphQL accepts non-JSON queries over POST',
'impact':'Possible Cross Site Request Forgery',
'severity':'MEDIUM',
'curl_verify':''
}

q = 'query {__typename}'

response = request(url, proxies=proxies, headers=headers, params={'query':q}, verb='POST')
res['curl_verify'] = curlify(response)

try:
if response and response.json()['data']['__typename']:
res['result'] = True
except:
pass

return res
9 changes: 6 additions & 3 deletions lib/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,22 +51,25 @@ def graph_query(url, proxies, headers, operation='query', payload={}, batch=Fals
return {}


def request_get(url, proxies, headers, params=None, data=None):
def request(url, proxies, headers, params=None, data=None, verb='GET'):
"""Perform requests."""
try:
response = requests.get(url,
response = requests.request(verb,
url=url,
params=params,
headers=headers,
cookies=None,
verify=False,
allow_redirects=True,
proxies=proxies,
timeout=5,
timeout=5,
data=data)
return response
except:
return None



def is_graphql(url, proxies, headers):
"""Check if the URL provides a GraphQL interface."""
query = '''
Expand Down
2 changes: 1 addition & 1 deletion version.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
"""Version details of graphql-cop."""
VERSION = '1.5'
VERSION = '1.6'

0 comments on commit 1948851

Please sign in to comment.