def process_api_resources(self): self.logger.info('Start preparation') for resource in self.api_resources['paths'].keys(): 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', {}): template_container_name = '{}|{}|{}'.format( normalized_url, method, param.get('name')) template = BaseTemplate(name=template_container_name) template.url = normalized_url template.method = method.upper() fuzz_type = get_fuzz_type_by_param_type( transform_data_to_bytes(param.get( 'type'))) # gives RandomBitsField at the moment sample_data = get_sample_data_by_type(param.get('type')) # get parameter placement(in): path, query, header, cookie # get parameter type: integer, string # get format if present param_type = param.get('in') param_name = template_container_name self.logger.debug( 'Resource: {} Method: {} Parameter: {}, Parameter type: {}, Sample data: {},' 'Param name: {}'.format(resource, method, param, param_type, sample_data, param_name)) if param_type == ParamTypes.PATH: template.path_variables.append( fuzz_type(name=param_name, value=str(sample_data))) elif param_type == ParamTypes.HEADER: template.headers.append( fuzz_type( name=param_name, value=transform_data_to_bytes(sample_data))) elif param_type == ParamTypes.COOKIE: template.cookies.append( fuzz_type(name=param_name, value=sample_data)) elif param_type == ParamTypes.QUERY: template.params.append( fuzz_type(name=param_name, value=str(sample_data))) elif param_type in [ParamTypes.BODY, ParamTypes.FORM_DATA]: template.data.append( fuzz_type( name=param_name, value=transform_data_to_bytes(sample_data))) else: self.logger.error( 'Can not parse a definition from swagger.json: %s', param) self.templates.append(template)
def _get_template(self, template_name): """ Starts new template if it does not exist yet or retrun the existing one which has the required name :param template_name: name of the template :type template_name: str :return: instance of BaseTemplate """ _return = None for template in self.templates: self.logger.debug(f'Checking {template.name} vs {template_name}') if template.name == template_name: self.logger.debug( f'Loading existing template: {template.name}') _return = template if not _return: self.logger.debug(f'Open new Fuzz template for {template_name}') _return = BaseTemplate(name=template_name) return _return
def process_api_resources(self, paths=None): self.logger.info('Start preparation') tmp_api_resource = dict() if not paths: paths = self.api_resources['paths'] else: self.logger.info('Processing extra parameter: {}'.format( pretty_print(paths, limit=300))) for resource in paths.keys(): normalized_url = self.normalize_url(resource) for method in paths[resource].keys(): self.logger.info('Resource: {} Method: {}'.format( resource, method)) template_container_name = '{}|{}'.format( normalized_url, method) template = BaseTemplate(name=template_container_name) template.url = normalized_url template.method = method.upper() params_to_process = list(paths[resource][method].get( 'parameters', {})) params_to_process.append(paths[resource][method].get( 'requestBody', {})) for param in params_to_process: self.logger.info('Processing parameter: {}'.format(param)) if not isinstance(param, dict): self.logger.warning( '{} type mismatch, dict expected, got: {}'.format( param, type(param))) param = json.loads(param) if param.get('type'): parameter_data_type = param.get('type') elif param.get('schema', {}).get('type'): parameter_data_type = param.get('schema', {}).get('type') else: parameter_data_type = 'string' param_format = param.get('format') if param_format is not None: fuzzer_type = param_format.lower() elif parameter_data_type is not None: fuzzer_type = parameter_data_type.lower() else: fuzzer_type = None fuzz_type = get_fuzz_type_by_param_type(fuzzer_type) if param.get('example'): sample_data = param.get('example') elif param.get('schema', {}).get('example'): sample_data = param.get('schema', {}).get('example') else: sample_data = get_sample_data_by_type( param.get('type')) # get parameter placement(in): path, query, header, cookie # get parameter type: integer, string # get format if present parameter_place_in_request = param.get('in') param_name = '{}|{}'.format(template_container_name, param.get('name')) self.logger.debug( 'Resource: {} Method: {} Parameter: {}, Parameter type: {}, Sample data: {},' 'Param name: {}, fuzzer: {}'.format( resource, method, param, parameter_place_in_request, sample_data, param_name, fuzz_type.__name__)) if parameter_place_in_request == ParamTypes.PATH: template.path_variables.append( fuzz_type(name=param_name, value=str(sample_data))) elif parameter_place_in_request == ParamTypes.HEADER: template.headers.append( fuzz_type( name=param_name, value=transform_data_to_bytes(sample_data))) elif parameter_place_in_request == ParamTypes.COOKIE: template.cookies.append( fuzz_type(name=param_name, value=sample_data)) elif parameter_place_in_request == ParamTypes.QUERY: template.params.append( fuzz_type(name=param_name, value=str(sample_data))) elif parameter_place_in_request == ParamTypes.BODY: template.data.append( fuzz_type( name=param_name, value=transform_data_to_bytes(sample_data))) elif parameter_place_in_request == ParamTypes.FORM_DATA: template.params.append( fuzz_type(name=param_name, value=str(sample_data))) elif len(param.get('$ref', "")): self.logger.info( 'Only schema reference found in the parameter description: {}' .format(param)) tweaked_param = {'schema': param} tmp_api_resource = self.process_schema( resource, method, tweaked_param, tmp_api_resource) else: self.logger.error('Can not parse a definition: %s', param) if param.get('schema'): tmp_api_resource = self.process_schema( resource, method, param, tmp_api_resource) self.logger.info( 'Adding template to list: {}, templates list: {}'.format( template.name, len(self.templates) + 1)) self.templates.append(template) if len(tmp_api_resource) > 0: self.logger.info( 'Additional resources were found, processing these: {}'.format( pretty_print(tmp_api_resource))) self.process_api_resources(paths=tmp_api_resource)