def test_fuzzable_request_list(self): profile, target_url = get_test_profile() data = {'scan_profile': profile, 'target_urls': [target_url]} response = self.app.post('/scans/', data=json.dumps(data), headers=self.HEADERS) scan_id = json.loads(response.data)['id'] # # Wait until the scanner finishes and assert the vulnerabilities # self.wait_until_running() self.wait_until_finish() # # Get all the URLs that the scanner found # response = self.app.get('/scans/%s/fuzzable-requests/' % scan_id, headers=self.HEADERS) self.assertEqual(response.status_code, 200, response.data) encoded_fuzzable_requests_items = json.loads(response.data)['items'] decoded_fuzzable_requests = [] for encoded_fr in encoded_fuzzable_requests_items: decoded_fr = base64.b64decode(encoded_fr) decoded_fuzzable_requests.append(decoded_fr) self.assertEqual(set(decoded_fuzzable_requests), set(EXPECTED_FUZZABLE_REQUESTS))
def test_url_list(self): profile, target_url = get_test_profile() data = {'scan_profile': profile, 'target_urls': [target_url]} response = self.app.post('/scans/', data=json.dumps(data), headers=self.HEADERS) scan_id = json.loads(response.data)['id'] # # Wait until the scanner finishes and assert the vulnerabilities # self.wait_until_running() self.wait_until_finish() # # Get all the URLs that the scanner found # response = self.app.get('/scans/%s/urls/' % scan_id, headers=self.HEADERS) self.assertEqual(response.status_code, 200, response.data) url_items = json.loads(response.data)['items'] expected_urls = [target_url, u'%s/where_integer_qs.py' % target_url[:-1], u'%s/where_string_single_qs.py' % target_url[:-1], u'%s/where_integer_form.py' % target_url[:-1]] self.assertEqual(set(url_items), set(expected_urls))
def test_fuzzable_request_list(self): profile, target_url = get_test_profile() data = {'scan_profile': profile, 'target_urls': [target_url]} response = self.app.post('/scans/', data=json.dumps(data), headers=self.HEADERS) scan_id = json.loads(response.data)['id'] # # Wait until the scanner finishes and assert the vulnerabilities # self.wait_until_running() self.wait_until_finish() # # Get all the URLs that the scanner found # response = self.app.get('/scans/%s/fuzzable-requests/' % scan_id, headers=self.HEADERS) self.assertEqual(response.status_code, 200, response.data) encoded_fuzzable_requests_items = json.loads(response.data)['items'] decoded_fuzzable_requests = [] for encoded_fr in encoded_fuzzable_requests_items: decoded_fr = base64.b64decode(encoded_fr) decoded_fuzzable_requests.append(decoded_fr) self.assertEqual(set(decoded_fuzzable_requests), set(EXPECTED_FUZZABLE_REQUESTS))
def test_url_list(self): profile, target_url = get_test_profile() data = {'scan_profile': profile, 'target_urls': [target_url]} response = self.app.post('/scans/', data=json.dumps(data), headers=self.HEADERS) scan_id = json.loads(response.data)['id'] # # Wait until the scanner finishes and assert the vulnerabilities # self.wait_until_running() self.wait_until_finish() # # Get all the URLs that the scanner found # response = self.app.get('/scans/%s/urls/' % scan_id, headers=self.HEADERS) self.assertEqual(response.status_code, 200, response.data) url_items = json.loads(response.data)['items'] expected_urls = [ target_url, u'%s/where_integer_qs.py' % target_url[:-1], u'%s/where_string_single_qs.py' % target_url[:-1], u'%s/where_integer_form.py' % target_url[:-1] ] self.assertEqual(set(url_items), set(expected_urls))
def test_kb_filters(self): profile, target_url = get_test_profile() data = {'scan_profile': profile, 'target_urls': [target_url]} response = requests.post('%s/scans/' % self.api_url, data=json.dumps(data), headers=self.headers) scan_id = response.json()['id'] # # Wait until the scanner finishes and assert the vulnerabilities # self.wait_until_running() self.wait_until_finish() # # Name filter # args = (self.api_url, scan_id) response = requests.get('%s/scans/%s/kb/?name=SQL%%20Injection' % args) self.assertEqual(response.status_code, 200, response.text) vuln_items = response.json()['items'] self.assertEqual(4, len(vuln_items), self.create_assert_message()) response = requests.get('%s/scans/%s/kb/?name=Foo' % args) self.assertEqual(response.status_code, 200, response.text) vuln_items = response.json()['items'] self.assertEqual(0, len(vuln_items)) # # URL filter # extra_args = (self.api_url, scan_id, target_url) response = requests.get('%s/scans/%s/kb/?url=%s' % extra_args) self.assertEqual(response.status_code, 200, response.text) vuln_items = response.json()['items'] self.assertEqual(4, len(vuln_items)) response = requests.get('%s/scans/%s/kb/?url=http://google.com/' % args) self.assertEqual(response.status_code, 200, response.text) vuln_items = response.json()['items'] self.assertEqual(0, len(vuln_items)) # # Combined filter # qs = '%s/scans/%s/kb/?url=%s&name=SQL%%20injection' response = requests.get(qs % extra_args) self.assertEqual(response.status_code, 200, response.text) vuln_items = response.json()['items'] self.assertEqual(4, len(vuln_items))
def test_auth(self): profile, target_url = get_test_profile() data = {'scan_profile': profile, 'target_urls': [target_url]} # I'm not sending any authentication in this request headers = self.HEADERS.copy() headers.pop('Authorization') response = self.app.post('/scans/', data=json.dumps(data), headers=headers) code = json.loads(response.data)['code'] self.assertEqual(code, 401) self.assertEqual(response.status_code, 401)
def test_auth(self): profile, target_url = get_test_profile() data = {'scan_profile': profile, 'target_urls': [target_url]} # I'm not sending any authentication in this request headers = self.HEADERS.copy() headers.pop('Authorization') response = self.app.post('/scans/', data=json.dumps(data), headers=headers) code = json.loads(response.data)['code'] self.assertEqual(code, 401) self.assertEqual(response.status_code, 401)
def test_require_json_header(self): profile, target_url = get_test_profile() data = {'scan_profile': profile, 'target_urls': [target_url]} # I'm not sending any content-type in this request headers = self.HEADERS.copy() headers.pop('Content-type') response = self.app.post('/scans/', data=json.dumps(data), headers=headers) error = json.loads(response.data) self.assertEqual(error['code'], 400) self.assertEqual(error['message'], NO_HEADER) self.assertEqual(response.status_code, 400)
def test_require_json_header(self): profile, target_url = get_test_profile() data = {'scan_profile': profile, 'target_urls': [target_url]} # I'm not sending any content-type in this request headers = self.HEADERS.copy() headers.pop('Content-type') response = self.app.post('/scans/', data=json.dumps(data), headers=headers) error = json.loads(response.data) self.assertEqual(error['code'], 400) self.assertEqual(error['message'], NO_HEADER) self.assertEqual(response.status_code, 400)
def test_query_exceptions(self): profile, target_url = get_test_profile() data = {'scan_profile': profile, 'target_urls': [target_url]} response = self.app.post('/scans/', data=json.dumps(data), headers=self.HEADERS) scan_id = json.loads(response.data)['id'] self.wait_until_running() # Create an exception in the w3af scan response = self.app.post('/scans/%s/exceptions/' % scan_id, headers=self.HEADERS, data='{}') self.assertEqual(response.status_code, 201) # And now query it using the REST API response = self.app.get('/scans/%s/exceptions/' % scan_id, headers=self.HEADERS) exceptions = json.loads(response.data)['items'] self.assertEqual(len(exceptions), 1) exception = exceptions[0] self.assertIsInstance(exception['lineno'], int) exception.pop('lineno') expected_summary = { u'exception': u'unittest', u'function_name': u'exception_creator', u'href': u'/scans/0/exceptions/0', u'id': 0, #u'lineno': 123, u'phase': u'phase', u'plugin': u'plugin' } self.assertEqual(exception, expected_summary) response = self.app.get('/scans/%s/exceptions/0' % scan_id, headers=self.HEADERS) self.assertIn('traceback', json.loads(response.data))
def test_stop(self): profile, target_url = get_test_profile() data = {'scan_profile': profile, 'target_urls': [target_url]} response = requests.post('%s/scans/' % self.api_url, auth=self.api_auth, data=json.dumps(data), headers=self.headers, verify=False) self.assertEqual(response.json(), { u'message': u'Success', u'href': u'/scans/0', u'id': 0 }) self.assertEqual(response.status_code, 201) # # Wait until the scan is in Running state # self.wait_until_running() # # Now stop the scan # response = requests.get('%s/scans/0/stop' % self.api_url, auth=self.api_auth, verify=False) self.assertEqual(response.json(), {u'message': u'Stopping scan'}) # Wait for it... self.wait_until_finish() # Assert that we identify the logs associated with stopping the core response = requests.get('%s/scans/0/log' % self.api_url, auth=self.api_auth, verify=False) self.assertEqual(response.status_code, 200, response.text) log_data = response.json()['entries'] for entry in log_data: if 'The user stopped the scan' in entry['message']: break else: self.assertTrue(False, 'Stop not found in log')
def test_stop(self): profile, target_url = get_test_profile() data = {'scan_profile': profile, 'target_urls': [target_url]} response = requests.post('%s/scans/' % self.api_url, auth=self.api_auth, data=json.dumps(data), headers=self.headers, verify=False) self.assertEqual(response.json(), {u'message': u'Success', u'href': u'/scans/0', u'id': 0}) self.assertEqual(response.status_code, 201) # # Wait until the scan is in Running state # self.wait_until_running() # # Now stop the scan # response = requests.get('%s/scans/0/stop' % self.api_url, auth=self.api_auth, verify=False) self.assertEqual(response.json(), {u'message': u'Stopping scan'}) # Wait for it... self.wait_until_finish() # Assert that we identify the logs associated with stopping the core response = requests.get('%s/scans/0/log' % self.api_url, auth=self.api_auth, verify=False) self.assertEqual(response.status_code, 200, response.text) log_data = response.json()['entries'] for entry in log_data: if 'The user stopped the scan' in entry['message']: break else: self.assertTrue(False, 'Stop not found in log')
def test_query_exceptions(self): profile, target_url = get_test_profile() data = {'scan_profile': profile, 'target_urls': [target_url]} response = self.app.post('/scans/', data=json.dumps(data), headers=self.HEADERS) scan_id = json.loads(response.data)['id'] self.wait_until_running() # Create an exception in the w3af scan response = self.app.post('/scans/%s/exceptions/' % scan_id, headers=self.HEADERS, data='{}') self.assertEqual(response.status_code, 201) # And now query it using the REST API response = self.app.get('/scans/%s/exceptions/' % scan_id, headers=self.HEADERS) exceptions = json.loads(response.data)['items'] self.assertEqual(len(exceptions), 1) exception = exceptions[0] self.assertIsInstance(exception['lineno'], int) exception.pop('lineno') expected_summary = {u'exception': u'unittest', u'function_name': u'exception_creator', u'href': u'/scans/0/exceptions/0', u'id': 0, #u'lineno': 123, u'phase': u'phase', u'plugin': u'plugin'} self.assertEqual(exception, expected_summary) response = self.app.get('/scans/%s/exceptions/0' % scan_id, headers=self.HEADERS) self.assertIn('traceback', json.loads(response.data))
def test_scan_log(self): profile, target_url = get_test_profile(SLOW_TEST_PROFILE) data = {'scan_profile': profile, 'target_urls': [target_url]} requests.post('%s/scans/' % self.api_url, data=json.dumps(data), headers=self.headers) # # Wait until the scanner finishes and assert the vulnerabilities # self.wait_until_running() self.wait_until_finish(500) # # Get the scan log # response = requests.get('%s/scans/0/log' % self.api_url) self.assertEqual(response.status_code, 200, response.text) log_data_page_0 = response.json() self.assertEqual(len(log_data_page_0['entries']), 200) self.assertEqual(log_data_page_0['more'], True) self.assertEqual(log_data_page_0['next'], 1) zero_entry = log_data_page_0['entries'][0] self.assertEqual(zero_entry['message'], u'Called w3afCore.start()') self.assertEqual(zero_entry['severity'], None) self.assertEqual(zero_entry['type'], 'debug') self.assertIsNotNone(zero_entry['time']) response = requests.get('%s/scans/0/log?page=1' % self.api_url) self.assertEqual(response.status_code, 200, response.text) self.assertNotEqual(log_data_page_0['entries'], response.json()['entries'])
def test_kb_filters(self): profile, target_url = get_test_profile() data = {'scan_profile': profile, 'target_urls': [target_url]} response = self.app.post('/scans/', data=json.dumps(data), headers=self.HEADERS) scan_id = json.loads(response.data)['id'] # # Wait until the scanner finishes and assert the vulnerabilities # self.wait_until_running() self.wait_until_finish() # # Name filter # response = self.app.get('/scans/%s/kb/?name=SQL%%20Injection' % scan_id, headers=self.HEADERS) self.assertEqual(response.status_code, 200, response.data) vuln_items = json.loads(response.data)['items'] self.assertEqual(4, len(vuln_items), vuln_items) response = self.app.get('/scans/%s/kb/?name=Foo' % scan_id, headers=self.HEADERS) self.assertEqual(response.status_code, 200, response.data) vuln_items = json.loads(response.data)['items'] self.assertEqual(0, len(vuln_items)) # # URL filter # extra_args = (scan_id, target_url) response = self.app.get('/scans/%s/kb/?url=%s' % extra_args, headers=self.HEADERS) self.assertEqual(response.status_code, 200, response.data) vuln_items = json.loads(response.data)['items'] self.assertEqual(4, len(vuln_items)) response = self.app.get('/scans/%s/kb/?url=http://google.com/' % scan_id, headers=self.HEADERS) self.assertEqual(response.status_code, 200, response.data) vuln_items = json.loads(response.data)['items'] self.assertEqual(0, len(vuln_items)) # # Combined filter # qs = '/scans/%s/kb/?url=%s&name=SQL%%20injection' response = self.app.get(qs % extra_args, headers=self.HEADERS) self.assertEqual(response.status_code, 200, response.data) vuln_items = json.loads(response.data)['items'] self.assertEqual(4, len(vuln_items))
def test_kb_filters(self): profile, target_url = get_test_profile() data = {'scan_profile': profile, 'target_urls': [target_url]} response = self.app.post('/scans/', data=json.dumps(data), headers=self.HEADERS) scan_id = json.loads(response.data)['id'] # # Wait until the scanner finishes and assert the vulnerabilities # self.wait_until_running() self.wait_until_finish() # # Name filter # response = self.app.get('/scans/%s/kb/?name=SQL%%20Injection' % scan_id, headers=self.HEADERS) self.assertEqual(response.status_code, 200, response.data) vuln_items = json.loads(response.data)['items'] self.assertEqual(4, len(vuln_items), vuln_items) response = self.app.get('/scans/%s/kb/?name=Foo' % scan_id, headers=self.HEADERS) self.assertEqual(response.status_code, 200, response.data) vuln_items = json.loads(response.data)['items'] self.assertEqual(0, len(vuln_items)) # # URL filter # extra_args = (scan_id, target_url) response = self.app.get('/scans/%s/kb/?url=%s' % extra_args, headers=self.HEADERS) self.assertEqual(response.status_code, 200, response.data) vuln_items = json.loads(response.data)['items'] self.assertEqual(4, len(vuln_items)) response = self.app.get('/scans/%s/kb/?url=http://google.com/' % scan_id, headers=self.HEADERS) self.assertEqual(response.status_code, 200, response.data) vuln_items = json.loads(response.data)['items'] self.assertEqual(0, len(vuln_items)) # # Combined filter # qs = '/scans/%s/kb/?url=%s&name=SQL%%20injection' response = self.app.get(qs % extra_args, headers=self.HEADERS) self.assertEqual(response.status_code, 200, response.data) vuln_items = json.loads(response.data)['items'] self.assertEqual(4, len(vuln_items))
def test_scan_log(self): profile, target_url = get_test_profile(SLOW_TEST_PROFILE) data = {'scan_profile': profile, 'target_urls': [target_url]} response = self.app.post('/scans/', data=json.dumps(data), headers=self.HEADERS) scan_id = json.loads(response.data)['id'] # # Wait until the scanner finishes and assert the vulnerabilities # self.wait_until_running() self.wait_until_finish(500) # # Get the scan log paginating by "page" # response = self.app.get('/scans/%s/log' % scan_id, headers=self.HEADERS) self.assertEqual(response.status_code, 200, response.data) log_data_page_0 = json.loads(response.data) entries = log_data_page_0['entries'] self.assertEqual(len(entries), 200, entries) self.assertEqual(log_data_page_0['next'], 1) self.assertEqual(log_data_page_0['next_url'], '/scans/%s/log?page=1' % scan_id) zero_entry = log_data_page_0['entries'][0] self.assertEqual(zero_entry['message'], u'Called w3afCore.start()') self.assertEqual(zero_entry['severity'], None) self.assertEqual(zero_entry['type'], 'debug') self.assertIsInstance(zero_entry['id'], int) self.assertIsNotNone(zero_entry['time']) response = self.app.get('/scans/%s/log?page=1' % scan_id, headers=self.HEADERS) self.assertEqual(response.status_code, 200, response.data) self.assertNotEqual(log_data_page_0['entries'], json.loads(response.data)['entries']) # # Get the scan log paginating by "id" # response = self.app.get('/scans/%s/log?id=0' % scan_id, headers=self.HEADERS) self.assertEqual(response.status_code, 200, response.data) log_data_page_0 = json.loads(response.data) entries = log_data_page_0['entries'] self.assertEqual(len(entries), 200, entries) self.assertEqual(log_data_page_0['next'], 200) self.assertEqual(log_data_page_0['next_url'], '/scans/%s/log?id=200' % scan_id) zero_entry = log_data_page_0['entries'][0] self.assertEqual(zero_entry['message'], u'Called w3afCore.start()') self.assertEqual(zero_entry['severity'], None) self.assertEqual(zero_entry['type'], 'debug') self.assertEqual(zero_entry['id'], 0) self.assertIsNotNone(zero_entry['time']) response = self.app.get('/scans/%s/log?id=200' % scan_id, headers=self.HEADERS) self.assertEqual(response.status_code, 200, response.data) self.assertNotEqual(log_data_page_0['entries'], json.loads(response.data)['entries'])
def test_start_simple_scan(self): profile, target_url = get_test_profile() data = {'scan_profile': profile, 'target_urls': [target_url]} response = requests.post('%s/scans/' % self.api_url, auth=self.api_auth, data=json.dumps(data), headers=self.headers, verify=False) scan_id = response.json()['id'] self.assertEqual(response.json(), {u'message': u'Success', u'href': u'/scans/%s' % scan_id, u'id': scan_id}) self.assertEqual(response.status_code, 201) # # Wait until the scan is in Running state # response = self.wait_until_running() self.assertEqual(response.status_code, 200, response.text) list_response = {u'items': [{u'href': u'/scans/%s' % scan_id, u'id': scan_id, u'status': u'Running', u'errors': False, u'target_urls': [target_url]}]} self.assertEqual(response.json(), list_response) # # Get the detailed status # response = requests.get('%s/scans/%s/status' % (self.api_url, scan_id), auth=self.api_auth, verify=False) self.assertEqual(response.status_code, 200, response.text) json_data = response.json() self.assertEqual(json_data['is_running'], True) self.assertEqual(json_data['is_paused'], False) self.assertEqual(json_data['exception'], None) # # Wait until the scanner finishes and assert the vulnerabilities # self.wait_until_finish() response = requests.get('%s/scans/%s/kb/' % (self.api_url, scan_id), auth=self.api_auth, verify=False) self.assertEqual(response.status_code, 200, response.text) vuln_summaries = response.json()['items'] names = set([v['name'] for v in vuln_summaries]) urls = set([v['url'] for v in vuln_summaries]) self.assertEqual(4, len(vuln_summaries)) self.assertEqual(names, set(get_expected_vuln_names())) self.assertEqual(urls, set(get_expected_vuln_urls(target_url))) # # Make sure I can access the vulnerability details # response = requests.get('%s/scans/%s/kb/0' % (self.api_url, scan_id), auth=self.api_auth, verify=False) self.assertEqual(response.status_code, 200, response.text) vuln_info = response.json() self.assertEqual(vuln_info['plugin_name'], 'sqli') self.assertEqual(vuln_info['href'], '/scans/%s/kb/0' % scan_id) self.assertEqual(vuln_info['id'], 0) self.assertEqual(vuln_info['fix_effort'], 50) self.assertEqual(vuln_info['cwe_ids'], ['89']) self.assertEqual(vuln_info['severity'], 'High') self.assertEqual(vuln_info['tags'], [u'web', u'sql', u'injection', u'database', u'error']) # # Get the HTTP traffic for this vulnerability # traffic_href = vuln_info['traffic_hrefs'][0] response = requests.get('%s%s' % (self.api_url, traffic_href), auth=self.api_auth, verify=False) traffic_data = response.json() self.assertIn('request', traffic_data) self.assertIn('response', traffic_data) self.assertIn('GET ', base64.b64decode(traffic_data['request'])) # # Get the scan log # response = requests.get('%s/scans/%s/log' % (self.api_url, scan_id), auth=self.api_auth, verify=False) self.assertEqual(response.status_code, 200, response.text) log_data = response.json() self.assertGreater(len(log_data['entries']), 100) self.assertEqual(log_data['next'], None) self.assertEqual(log_data['next_url'], None) zero_entry = log_data['entries'][0] self.assertEqual(zero_entry['message'], u'Called w3afCore.start()') self.assertEqual(zero_entry['severity'], None) self.assertEqual(zero_entry['type'], 'debug') self.assertIsNotNone(zero_entry['id']) self.assertIsNotNone(zero_entry['time']) # # Clear the scan results # response = requests.delete('%s/scans/%s' % (self.api_url, scan_id), auth=self.api_auth, verify=False) self.assertEqual(response.json(), {u'message': u'Success'}) return scan_id
def test_scan_log(self): profile, target_url = get_test_profile(SLOW_TEST_PROFILE) data = {'scan_profile': profile, 'target_urls': [target_url]} response = self.app.post('/scans/', data=json.dumps(data), headers=self.HEADERS) scan_id = json.loads(response.data)['id'] # # Wait until the scanner finishes and assert the vulnerabilities # self.wait_until_running() self.wait_until_finish(500) # # Get the scan log paginating by "page" # response = self.app.get('/scans/%s/log' % scan_id, headers=self.HEADERS) self.assertEqual(response.status_code, 200, response.data) log_data_page_0 = json.loads(response.data) entries = log_data_page_0['entries'] self.assertEqual(len(entries), 200, entries) self.assertEqual(log_data_page_0['next'], 1) self.assertEqual(log_data_page_0['next_url'], '/scans/%s/log?page=1' % scan_id) zero_entry = log_data_page_0['entries'][0] self.assertEqual(zero_entry['message'], u'Called w3afCore.start()') self.assertEqual(zero_entry['severity'], None) self.assertEqual(zero_entry['type'], 'debug') self.assertIsNotNone(zero_entry['time']) response = self.app.get('/scans/%s/log?page=1' % scan_id, headers=self.HEADERS) self.assertEqual(response.status_code, 200, response.data) self.assertNotEqual(log_data_page_0['entries'], json.loads(response.data)['entries']) # # Get the scan log paginating by "id" # response = self.app.get('/scans/%s/log?id=0' % scan_id, headers=self.HEADERS) self.assertEqual(response.status_code, 200, response.data) log_data_page_0 = json.loads(response.data) entries = log_data_page_0['entries'] self.assertEqual(len(entries), 200, entries) self.assertEqual(log_data_page_0['next'], 200) self.assertEqual(log_data_page_0['next_url'], '/scans/%s/log?id=200' % scan_id) zero_entry = log_data_page_0['entries'][0] self.assertEqual(zero_entry['message'], u'Called w3afCore.start()') self.assertEqual(zero_entry['severity'], None) self.assertEqual(zero_entry['type'], 'debug') self.assertEqual(zero_entry['id'], 0) self.assertIsNotNone(zero_entry['time']) response = self.app.get('/scans/%s/log?id=200' % scan_id, headers=self.HEADERS) self.assertEqual(response.status_code, 200, response.data) self.assertNotEqual(log_data_page_0['entries'], json.loads(response.data)['entries'])
def test_start_simple_scan(self): profile, target_url = get_test_profile() data = {'scan_profile': profile, 'target_urls': [target_url]} response = requests.post('%s/scans/' % self.api_url, auth=self.api_auth, data=json.dumps(data), headers=self.headers) scan_id = response.json()['id'] self.assertEqual( response.json(), { u'message': u'Success', u'href': u'/scans/%s' % scan_id, u'id': scan_id }) self.assertEqual(response.status_code, 201) # # Wait until the scan is in Running state # response = self.wait_until_running() self.assertEqual(response.status_code, 200, response.text) list_response = { u'items': [{ u'href': u'/scans/%s' % scan_id, u'id': scan_id, u'status': u'Running', u'errors': False, u'target_urls': [target_url] }] } self.assertEqual(response.json(), list_response) # # Get the detailed status # response = requests.get('%s/scans/%s/status' % (self.api_url, scan_id), auth=self.api_auth) self.assertEqual(response.status_code, 200, response.text) json_data = response.json() self.assertEqual(json_data['is_running'], True) self.assertEqual(json_data['is_paused'], False) self.assertEqual(json_data['exception'], None) # # Wait until the scanner finishes and assert the vulnerabilities # self.wait_until_finish() response = requests.get('%s/scans/%s/kb/' % (self.api_url, scan_id), auth=self.api_auth) self.assertEqual(response.status_code, 200, response.text) vuln_summaries = response.json()['items'] names = set([v['name'] for v in vuln_summaries]) urls = set([v['url'] for v in vuln_summaries]) self.assertEqual(4, len(vuln_summaries)) self.assertEqual(names, set(get_expected_vuln_names())) self.assertEqual(urls, set(get_expected_vuln_urls(target_url))) # # Make sure I can access the vulnerability details # response = requests.get('%s/scans/%s/kb/0' % (self.api_url, scan_id), auth=self.api_auth) self.assertEqual(response.status_code, 200, response.text) vuln_info = response.json() self.assertEqual(vuln_info['plugin_name'], 'sqli') self.assertEqual(vuln_info['href'], '/scans/%s/kb/0' % scan_id) self.assertEqual(vuln_info['id'], 0) self.assertEqual(vuln_info['fix_effort'], 50) self.assertEqual(vuln_info['cwe_ids'], ['89']) self.assertEqual(vuln_info['severity'], 'High') self.assertEqual(vuln_info['tags'], [u'web', u'sql', u'injection', u'database', u'error']) # # Get the HTTP traffic for this vulnerability # traffic_href = vuln_info['traffic_hrefs'][0] response = requests.get('%s%s' % (self.api_url, traffic_href), auth=self.api_auth) traffic_data = response.json() self.assertIn('request', traffic_data) self.assertIn('response', traffic_data) self.assertIn('GET ', base64.b64decode(traffic_data['request'])) # # Get the scan log # response = requests.get('%s/scans/%s/log' % (self.api_url, scan_id), auth=self.api_auth) self.assertEqual(response.status_code, 200, response.text) log_data = response.json() self.assertGreater(len(log_data['entries']), 100) self.assertEqual(log_data['next'], None) self.assertEqual(log_data['next_url'], None) zero_entry = log_data['entries'][0] self.assertEqual(zero_entry['message'], u'Called w3afCore.start()') self.assertEqual(zero_entry['severity'], None) self.assertEqual(zero_entry['type'], 'debug') self.assertIsNotNone(zero_entry['id']) self.assertIsNotNone(zero_entry['time']) # # Clear the scan results # response = requests.delete('%s/scans/%s' % (self.api_url, scan_id), auth=self.api_auth) self.assertEqual(response.json(), {u'message': u'Success'}) return scan_id