Skip to content

Commit

Permalink
#22 report saved
Browse files Browse the repository at this point in the history
  • Loading branch information
KissPeter committed Oct 4, 2019
1 parent c581087 commit 10dd55a
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 73 deletions.
99 changes: 41 additions & 58 deletions apifuzzer/fuzzer_target.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@

import json
import os
from time import time
import re
import requests
from base64 import b64encode
from bitstring import Bits
from time import time

import requests
from bitstring import Bits
from kitty.data.report import Report
from kitty.targets.server import ServerTarget
from requests.exceptions import RequestException

from apifuzzer.utils import set_class_logger,transform_data_to_bytes
from apifuzzer.utils import set_class_logger


@set_class_logger
Expand All @@ -29,60 +30,26 @@ def __init__(self, name, base_url, report_dir, logger):
self.logger = logger
self.logger.info('Logger initialized')

def try_b64encode(self, data_in):
@staticmethod
def try_b64encode(data_in):
try:
return b64encode(data_in)
except TypeError:
return data_in

def error_report(self, msg, req):
if hasattr(req, 'request'):
self.report.add('request method', req.request.method)
self.report.add('request body', req.request.body)
self.report.add('response', req.text)
else:
for k, v in req.items():
if isinstance(v, dict):
for subkey, subvalue in v.items():
try:
self.report.add(subkey, self.try_b64encode(subvalue))
except TypeError:
self.logger.error('Failed to add field ({}) or value ({}) to report because '
'unsupported type ({}), report the issue'.format(subkey, subvalue,
type(subvalue)))
else:
self.report.add(k, self.try_b64encode(subvalue))
self.report.set_status(Report.ERROR)
self.report.error(msg)

def save_report_to_disc(self):
try:
if not os.path.exists(os.path.dirname(self.report_dir)):
try:
os.makedirs(os.path.dirname(self.report_dir))
except OSError:
pass
with open('{}/{}_{}.json'.format(self.report_dir, self.test_number, time()), 'wb') as report_dump_file:
report_dump_file.write(json.dumps(self.report.to_dict()))
except Exception as e:
self.logger.error('Failed to save report "{}" to {} because: {}'
.format(self.report, self.report_dir, e))

def transmit(self, **kwargs):
self.logger.debug('Transmit: {}'.format(kwargs))
try:
_req_url = list()
for url_part in self.base_url, kwargs['url']:
self.logger.info('URL part: {}, type {}'.format(url_part, type(url_part)))
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()
# url_part= transform_data_to_bytes(url_part).decode()
self.logger.info('URL part 2: {}, type {}'.format(url_part, type(url_part)))
# _req_url.append(url_part.strip('/'))
_req_url.append(url_part)
self.logger.warn('Request KWARGS:{}, url: {}'.format(kwargs, _req_url))
self.logger.debug('Request kwargs:{}, url: {}'.format(kwargs, _req_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'))
Expand All @@ -93,33 +60,49 @@ def transmit(self, **kwargs):
kwargs.pop('path_variables')
kwargs.pop('url')
method = kwargs['method']
if isinstance(method , Bits):
method = method .tobytes()
if isinstance(method , bytes):
method = method .decode()
if isinstance(method, Bits):
method = method.tobytes()
if isinstance(method, bytes):
method = method.decode()
kwargs.pop('method')
_return = requests.request(method=method, url=request_url, **kwargs)
self.report.set_status(Report.PASSED)
self.report.add('request method', _return.request.method)
self.report.add('request body', _return.request.body)
self.report.add('response', _return.text)
status_code = _return.status_code
if status_code:
if status_code not in self.accepted_status_codes:
self.report.add('parsed status_code', status_code)
self.report.add('request method', _return.request.method)
self.report.add('request body', _return.request.body)
self.report.add('response', _return.text)
self.report.set_status(Report.FAILED)
self.report.failed('return code {} is not in the expected list'.format(status_code))
else:
self.error_report('Failed to parse http response code', _return.headers)
if not status_code:
self.report.set_status(Report.FAILED)
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.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.error_report('Failed to parse http response code, exception: {}'.format(e), kwargs)
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:
self.report.add('reason', self.report.get_name())
super(FuzzerTarget, self).post_test(test_num)
if self.report.get('status') != Report.PASSED:
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)):
try:
os.makedirs(os.path.dirname(self.report_dir))
except OSError:
pass
with open('{}/{}_{}.json'.format(self.report_dir, self.test_number, time()), 'w') as report_dump_file:
report_dump_file.write(json.dumps(self.report.to_dict()))
except Exception as e:
self.logger.error('Failed to save report "{}" to {} because: {}'.format(self.report, self.report_dir, e))

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)))
Expand Down
26 changes: 11 additions & 15 deletions apifuzzer/server_fuzzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,17 @@ def _transmit(self, node):
for place in fuzz_places:
# self.logger.info('Transmit place: {}'.format(place))
try:
param = node.get_field_by_name(place)
# if isinstance(param, Container):
_result = self._recurse_params(param)
self.logger.info('Process param recursively: {} gives: {}'.format(param, _result))
payload[place] = _result
# elif hasattr(param, 'render'):
# payload[place] = param.render()
if place in node._fields_dict:
param = node.get_field_by_name(place)
# if isinstance(param, Container):
_result = self._recurse_params(param)
# self.logger.info('Process param recursively: {} gives: {}'.format(param, _result))
payload[place] = _result
# elif hasattr(param, 'render'):
# payload[place] = param.render()
except KittyException as e:
self.logger.warn('Exception occurred while processing {}: {}'.format(place, e.__str__()))
self.logger.info('Payload: {}'.format(payload))
# self.logger.info('Payload: {}'.format(payload))
self._last_payload = payload
try:
return self.target.transmit(**payload)
Expand Down Expand Up @@ -94,18 +95,13 @@ def _store_report(self, report):
if payload is not None:
data_report = Report('payload')
data_report.add('raw', payload)
try:
if isinstance(payload, dict):
data_report.add('hex', hexlify(json.dumps(str(payload), ensure_ascii=False)))
except (UnicodeDecodeError, TypeError):
print('Can not serialize payload: %', payload)
data_report.add('length', len(payload))
report.add('payload', data_report)
else:
report.add('payload', None)

# self.dataman.store_report(report, self.model.current_index())
# self.dataman.get_report_by_id(self.model.current_index())
self.dataman.store_report(report, self.model.current_index())
self.dataman.get_report_by_id(self.model.current_index())

def _test_environment(self):
sequence = self.model.get_sequence()
Expand Down

0 comments on commit 10dd55a

Please sign in to comment.