Skip to content

Commit

Permalink
path fuzzing fix
Browse files Browse the repository at this point in the history
  • Loading branch information
KissPeter committed Oct 4, 2019
1 parent 10dd55a commit b4db5cc
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 16 deletions.
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
language: python
python:
- '2.7'
- '3.4'
- '3.7'
env:
global:
- secure: nbvAVCvak6tOUf0K3zCfgM9W561j7i5AzzdfslkJK0qBeT4wTPrQ/EPx7Ay0X44Mk8rFlKlbDAvd1XuP6it1p8OFqDVWiyL2KObP4hh1duqjlg+xMJjO/wAHgQT8SUyk6BIQUnksUMS0wBqpuG2wsmG1B3zWspZpCpB/1XAfwJoG2DRyI5WNIII56pgn8tc57l7iPEmQrucPu7bWQoe4tYjMZCVewxc0rZgC2WLNPhaxuk1OwEJaTkNo8hetctfubnMvkx7JhKq9JgV9TI0CSHO6PYHHs8VvjmpC3kuWepqEVfnyyXYWFEsoPpL5q8bNnJbg/qvuhSlxM2VxJFzMmT5sXWQLKwR7VXHaIPho0jzmOgrL5BX3SlKXGAwLQ+vdrG7eeHJmZjzVUqzIK3NEseYH2u+iXLYSiNAXjdD3U3/NV5VWfbVgFx3yVhzWl1PdeCAe4zpPfllDqqG+WAfuYsYtseN+7+l7KMZjUL5Om+bzddK/jUrrG02U3XGqo1JjGO3rAT0JF9OuW6I+qhuFK8MD7+JAY7xR/cx71lgFgkympsJU3kQ1UKfUCs7aCUs6ask+OxixjUnEtZMEGA+MDdRNm6XLuedqkU0YgA2JgqJMbDt6vxaP5gdX26Jv/taO5m2U0tWM7iJkAtO2u3gpJtXhJvDyBisR/mHGiEGifPk=
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ Start the sample application (install the necessary packages listed in test/requ
$ python3 test/test_application.py
Start the fuzzer:
$ python3 fuzzer.py -s test/test_swagger_definition.json -u http://localhost:5000/ -r /tmp/reports/
$ python3 fuzzer.py -s test/test_swagger_definition.json -u http://127.0.0.1:5000/ -r /tmp/reports/ --log debug
Check the reports:
$ ls -1 /tmp/reports/
Expand Down
30 changes: 16 additions & 14 deletions apifuzzer/fuzzer_target.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,29 +42,29 @@ def transmit(self, **kwargs):
try:
_req_url = list()
for url_part in self.base_url, kwargs['url']:
self.logger.info('URL part 1: {}, type {}'.format(url_part, type(url_part)))
if isinstance(url_part, Bits):
url_part = url_part.tobytes()
if isinstance(url_part, bytes):
url_part = url_part.decode()
self.logger.info('URL part 2: {}, type {}'.format(url_part, type(url_part)))
_req_url.append(url_part)
self.logger.debug('Request kwargs:{}, url: {}'.format(kwargs, _req_url))
_req_url.append(url_part.strip('/'))
kwargs.pop('url')
request_url = '/'.join(_req_url)
if kwargs.get('path_variables') is not None:
request_url = self.expand_path_variables(request_url, kwargs.get('path_variables'))
kwargs.pop('path_variables')
if kwargs.get('params') is not None:
request_url = self.expand_path_variables(request_url, kwargs.get('params'))
kwargs.pop('params')
self.logger.info('Request URL : {}'.format(request_url ))
if kwargs.get('path_variables'):
kwargs.pop('path_variables')
kwargs.pop('url')
# if kwargs.get('path_variables'):
# kwargs.pop('path_variables')
method = kwargs['method']
if isinstance(method, Bits):
method = method.tobytes()
if isinstance(method, bytes):
method = method.decode()
kwargs.pop('method')
self.logger.debug('Request kwargs:{}, url: {}, method: {}'.format(kwargs, request_url, method))
_return = requests.request(method=method, url=request_url, **kwargs)
self.report.set_status(Report.PASSED)
self.report.add('request method', _return.request.method)
Expand All @@ -73,24 +73,27 @@ def transmit(self, **kwargs):
status_code = _return.status_code
if not status_code:
self.report.set_status(Report.FAILED)
self.logger.warn('Failed to parse http response code')
self.report.failed('Failed to parse http response code')
elif status_code not in self.accepted_status_codes:
self.report.add('Parsed status_code', status_code)
self.report.set_status(Report.FAILED)
self.logger.warn('Return code %s is not in the expected list', status_code)
self.report.failed(('Return code %s is not in the expected list', status_code))
return _return
except (RequestException, UnicodeDecodeError, UnicodeEncodeError) as e: # request failure such as InvalidHeader
self.report.set_status(Report.FAILED)
self.logger.warn('Failed to parse http response code, exception occurred')
self.report.failed('Failed to parse http response code, exception occurred')

def post_test(self, test_num):
"""Called after a test is completed, perform cleanup etc."""
if self.report.get('report') is None:
if self.report.get('report') is None:
self.report.add('reason', self.report.get_name())
super(FuzzerTarget, self).post_test(test_num)
if self.report.get_status() != Report.PASSED:
self.save_report_to_disc()


def save_report_to_disc(self):
try:
if not os.path.exists(os.path.dirname(self.report_dir)):
Expand All @@ -105,16 +108,15 @@ def save_report_to_disc(self):

def expand_path_variables(self, url, path_parameters):
if not isinstance(path_parameters, dict):
self.logger.error('Path_parameters {} does not in the desired format,received: {}'.format(path_parameters, type(path_parameters)))
self.logger.warn('Path_parameters {} does not in the desired format,received: {}'.format(path_parameters, type(path_parameters)))
return url
for path_key, path_value in path_parameters.items():
self.logger.info('Processing: path_key: {} , path_variable: {}'.format(path_key, path_value))
self.logger.debug('Processing: path_key: {} , path_variable: {}'.format(path_key, path_value))
try:
_temporally_url_list = list()
path_parameter = path_key.split('|')[-1]
splitter = '({' + path_parameter + '})'
url_list = re.split(splitter, url)
self.logger.info('Processing: {} key: {} splitter: {} '.format(url_list, path_parameter, splitter))
for url_part in url_list:
if url_part == '{' + path_parameter + '}':
_temporally_url_list.append(path_value)
Expand All @@ -123,9 +125,9 @@ def expand_path_variables(self, url, path_parameters):
_temporally_url_list.append(url_part)
# _temporally_url_list.append(url_part.encode())
url = "".join(_temporally_url_list)
self.logger.info('url 1: {} | {}->{}'.format(url, path_parameter, path_value))
# self.logger.info('Compiled url In {} + {}, out: {}'.format(url, path_parameter, path_value))
except Exception as e:
self.logger.warn('Failed to replace string in url: {} param: {}, exception: {}'.format(url, path_value, e))
url = url.replace("{", "").replace("}", "")
url = url.replace("{", "").replace("}", "").replace("+","/")
return url

7 changes: 6 additions & 1 deletion apifuzzer/swagger_template_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,15 @@ def __init__(self, api_resources, logger):
self.logger = logger
self.logger.info('Logger initialized')

def normalize_url(self, url_in):
# Kitty doesn't support some characters as tempalte name so need to be cleaned, but it is necessary, so
# we will change back later
return url_in.strip('/').replace('/','+')

def process_api_resources(self):
self.logger.info('Start preparation')
for resource in self.api_resources['paths'].keys():
normalized_url = resource.lstrip('/').replace('/', '_') #.replace('{','').replace('}','')
normalized_url = self.normalize_url(resource)
for method in self.api_resources['paths'][resource].keys():
self.logger.info('Resource: {} Method: {}'.format(resource, method))
for param in self.api_resources['paths'][resource][method].get('parameters', {}):
Expand Down

0 comments on commit b4db5cc

Please sign in to comment.