def test_number_of_new_false_positives(self): # Add a couple of false positives to database as new issues, # and check that the they're counted properly response = {'scenario_id': '1', 'req_headers': 'headers', 'req_body': 'body', 'url': 'url', 'req_method': 'method', 'timestamp': datetime.datetime.utcnow(), 'server_protocol_error': None, 'server_timeout': False, 'server_error_text_detected': False, 'server_error_text_matched': 'matched_text', 'resp_statuscode': 'statuscode', 'resp_headers': 'resp_headers', 'resp_body': 'resp_body', 'resp_history': 'resp_history'} # Add one, expect count to be 1 dbtools.add_false_positive(self.context, response) self.assertEqual(dbtools.number_of_new_in_database(self.context), 1, "After adding one, no one finding in database") # Add a second one, expect count to be 2 dbtools.add_false_positive(self.context, response) self.assertEqual(dbtools.number_of_new_in_database(self.context), 2, "After adding two, no two findings in db")
def test_number_of_new_false_positives(self): # Add a couple of false positives to database as new issues, # and check that the they're counted properly response = { 'scenario_id': '1', 'req_headers': 'headers', 'req_body': 'body', 'url': 'url', 'req_method': 'method', 'timestamp': datetime.datetime.utcnow(), 'server_protocol_error': None, 'server_timeout': False, 'server_error_text_detected': False, 'server_error_text_matched': 'matched_text', 'resp_statuscode': 'statuscode', 'resp_headers': 'resp_headers', 'resp_body': 'resp_body', 'resp_history': 'resp_history' } # Add one, expect count to be 1 dbtools.add_false_positive(self.context, response) self.assertEqual(dbtools.number_of_new_in_database(self.context), 1, "After adding one, no one finding in database") # Add a second one, expect count to be 2 dbtools.add_false_positive(self.context, response) self.assertEqual(dbtools.number_of_new_in_database(self.context), 2, "After adding two, no two findings in db")
def test_add_false_positive(self): # Add a false positive to database and check that all fields # get populated and can be compared back originals response = { 'scenario_id': '1', 'req_headers': 'headers', 'req_body': 'body', 'url': 'url', 'timestamp': datetime.datetime.utcnow(), 'req_method': 'method', 'server_protocol_error': None, 'server_timeout': False, 'server_error_text_detected': False, 'server_error_text_matched': 'matched_text', 'resp_statuscode': 'statuscode', 'resp_headers': 'resp_headers', 'resp_body': 'resp_body', 'resp_history': 'resp_history' } dbtools.add_false_positive(self.context, response) # Connect directly to the database and check the data is there db_engine = sqlalchemy.create_engine(self.context.dburl) dbconn = db_engine.connect() db_metadata = sqlalchemy.MetaData() httpfuzzer_issues = Table( 'httpfuzzer_issues', db_metadata, Column('new_issue', types.Boolean), Column('issue_no', types.Integer, primary_key=True, nullable=False), Column('timestamp', types.DateTime(timezone=True)), Column('test_runner_host', types.Text), Column('scenario_id', types.Text), Column('url', types.Text), Column('server_protocol_error', types.Text), Column('server_timeout', types.Boolean), Column('server_error_text_detected', types.Boolean), Column('server_error_text_matched', types.Text), Column('req_method', types.Text), Column('req_headers', types.LargeBinary), Column('req_body', types.LargeBinary), Column('resp_statuscode', types.Text), Column('resp_headers', types.LargeBinary), Column('resp_body', types.LargeBinary), Column('resp_history', types.LargeBinary)) db_select = sqlalchemy.sql.select([httpfuzzer_issues]) db_result = dbconn.execute(db_select) result = db_result.fetchone() for key, value in response.iteritems(): self.assertEqual(result[key], value, '%s not found in database after add' % key) self.assertEqual(result['test_runner_host'], socket.gethostbyname(socket.getfqdn()), 'Test runner host name not correct in database') self.assertLessEqual(result['timestamp'], datetime.datetime.utcnow(), 'Timestamp not correctly stored in database') dbconn.close()
def test_add_false_positive(self): # Add a false positive to database and check that all fields # get populated and can be compared back originals response = {'scenario_id': '1', 'req_headers': 'headers', 'req_body': 'body', 'url': 'url', 'timestamp': datetime.datetime.utcnow(), 'req_method': 'method', 'server_protocol_error': None, 'server_timeout': False, 'server_error_text_detected': False, 'server_error_text_matched': 'matched_text', 'resp_statuscode': 'statuscode', 'resp_headers': 'resp_headers', 'resp_body': 'resp_body', 'resp_history': 'resp_history'} dbtools.add_false_positive(self.context, response) # Connect directly to the database and check the data is there db_engine = sqlalchemy.create_engine(self.context.dburl) dbconn = db_engine.connect() db_metadata = sqlalchemy.MetaData() httpfuzzer_issues = Table('httpfuzzer_issues', db_metadata, Column('new_issue', types.Boolean), Column('issue_no', types.Integer, primary_key=True, nullable=False), Column('timestamp', types.DateTime(timezone=True)), Column('test_runner_host', types.Text), Column('scenario_id', types.Text), Column('url', types.Text), Column('server_protocol_error', types.Text), Column('server_timeout', types.Boolean), Column('server_error_text_detected', types.Boolean), Column('server_error_text_matched', types.Text), Column('req_method', types.Text), Column('req_headers', types.LargeBinary), Column('req_body', types.LargeBinary), Column('resp_statuscode', types.Text), Column('resp_headers', types.LargeBinary), Column('resp_body', types.LargeBinary), Column('resp_history', types.LargeBinary)) db_select = sqlalchemy.sql.select([httpfuzzer_issues]) db_result = dbconn.execute(db_select) result = db_result.fetchone() for key, value in response.iteritems(): self.assertEqual(result[key], value, '%s not found in database after add' % key) self.assertEqual(result['test_runner_host'], socket.gethostbyname(socket.getfqdn()), 'Test runner host name not correct in database') self.assertLessEqual(result['timestamp'], datetime.datetime.utcnow(), 'Timestamp not correctly stored in database') dbconn.close()
def step_impl(context): """Go through responses and save any that timed out into the database """ new_findings = 0 for response in context.responses: if response.get('server_timeout') is True: if fuzzdb.known_false_positive(context, response) is False: fuzzdb.add_false_positive(context, response) new_findings += 1 if new_findings > 0: context.new_findings += new_findings assert True
def step_impl(context): """Go through responses and store any with HTTP protocol errors (as caught by Requests) into the database """ new_findings = 0 for response in context.responses: if response.get('server_protocol_error') is not None: if fuzzdb.known_false_positive(context, response) is False: fuzzdb.add_false_positive(context, response) new_findings += 1 if new_findings > 0: context.new_findings += new_findings assert True
def step_impl(context, returncode_list): """Go through responses and store any with suspect return codes into the database """ disallowed_returncodes = unpack_integer_range(returncode_list) new_findings = 0 for response in context.responses: if response['resp_statuscode'] in disallowed_returncodes: if fuzzdb.known_false_positive(context, response) is False: fuzzdb.add_false_positive(context, response) new_findings += 1 if new_findings > 0: context.new_findings += new_findings assert True
def step_impl(context): """Go through responses and store any that contain a string from user-supplied list of strings into the database """ # Create a regex from the error response list error_list = [] for row in context.table: error_list.append(row['string']) error_list_regex = "(" + ")|(".join(error_list) + ")" # For each response, check that it isn't in the error response list new_findings = 0 for response in context.responses: if re.search(error_list_regex, response.get('resp_body'), re.IGNORECASE) is not None: response['server_error_text_detected'] = True if fuzzdb.known_false_positive(context, response) is False: fuzzdb.add_false_positive(context, response) new_findings += 1 if new_findings > 0: context.new_findings += new_findings assert True
def test_false_positive_detection(self): # Test whether false positives in database are identified properly response = {'scenario_id': '1', 'req_headers': 'headers', 'req_body': 'body', 'url': 'url', 'req_method': 'method', 'timestamp': datetime.datetime.utcnow(), 'server_protocol_error': False, 'server_timeout': False, 'server_error_text_detected': False, 'server_error_text_matched': 'matched_text', 'resp_statuscode': 'statuscode', 'resp_headers': 'resp_headers', 'resp_body': 'resp_body', 'resp_history': 'resp_history'} # First add one false positive and try checking against it dbtools.add_false_positive(self.context, response) self.assertEqual(dbtools.known_false_positive(self.context, response), True, "Duplicate false positive not detected") # Change one of the differentiating fields, and test, and # add the tested one to the database. response['scenario_id'] = '2' # Non-duplicate self.assertEqual(dbtools.known_false_positive(self.context, response), False, "Not a duplicate: scenario_id different") dbtools.add_false_positive(self.context, response) # Repeat for all the differentiating fields response['server_protocol_error'] = 'Error text' self.assertEqual(dbtools.known_false_positive(self.context, response), False, "Not a duplicate: server_protocol_error different") dbtools.add_false_positive(self.context, response) response['resp_statuscode'] = '500' self.assertEqual(dbtools.known_false_positive(self.context, response), False, "Not a duplicate: resp_statuscode different") dbtools.add_false_positive(self.context, response) response['server_timeout'] = True self.assertEqual(dbtools.known_false_positive(self.context, response), False, "Not a duplicate: server_timeout different") dbtools.add_false_positive(self.context, response) response['server_error_text_detected'] = True self.assertEqual(dbtools.known_false_positive(self.context, response), False, "Not a duplicate: server_error_text_detected different") dbtools.add_false_positive(self.context, response) # Finally, test the last one again twice, now it ought to be # reported back as a duplicate self.assertEqual(dbtools.known_false_positive(self.context, response), True, "A duplicate case not detected")
def test_false_positive_detection(self): # Test whether false positives in database are identified properly response = { 'scenario_id': '1', 'req_headers': 'headers', 'req_body': 'body', 'url': 'url', 'req_method': 'method', 'timestamp': datetime.datetime.utcnow(), 'server_protocol_error': False, 'server_timeout': False, 'server_error_text_detected': False, 'server_error_text_matched': 'matched_text', 'resp_statuscode': 'statuscode', 'resp_headers': 'resp_headers', 'resp_body': 'resp_body', 'resp_history': 'resp_history' } # First add one false positive and try checking against it dbtools.add_false_positive(self.context, response) self.assertEqual(dbtools.known_false_positive(self.context, response), True, "Duplicate false positive not detected") # Change one of the differentiating fields, and test, and # add the tested one to the database. response['scenario_id'] = '2' # Non-duplicate self.assertEqual(dbtools.known_false_positive(self.context, response), False, "Not a duplicate: scenario_id different") dbtools.add_false_positive(self.context, response) # Repeat for all the differentiating fields response['server_protocol_error'] = 'Error text' self.assertEqual(dbtools.known_false_positive(self.context, response), False, "Not a duplicate: server_protocol_error different") dbtools.add_false_positive(self.context, response) response['resp_statuscode'] = '500' self.assertEqual(dbtools.known_false_positive(self.context, response), False, "Not a duplicate: resp_statuscode different") dbtools.add_false_positive(self.context, response) response['server_timeout'] = True self.assertEqual(dbtools.known_false_positive(self.context, response), False, "Not a duplicate: server_timeout different") dbtools.add_false_positive(self.context, response) response['server_error_text_detected'] = True self.assertEqual( dbtools.known_false_positive(self.context, response), False, "Not a duplicate: server_error_text_detected different") dbtools.add_false_positive(self.context, response) # Finally, test the last one again twice, now it ought to be # reported back as a duplicate self.assertEqual(dbtools.known_false_positive(self.context, response), True, "A duplicate case not detected")