def test_render_with_special_chars(self): _id = 2 desc = ('This is a long description that contains some special' ' characters such as <, & and > which MUST be encoded' ' by jinja2.') vuln = MockVuln(_id=_id) vuln.set_desc(desc) url = URL('http://w3af.com/a/b/c.php') hdr = Headers([('User-Agent', 'w3af')]) request = HTTPRequest(url, data='a=1') request.set_headers(hdr) hdr = Headers([('Content-Type', 'text/html')]) res = HTTPResponse(200, '<html>', hdr, url, url) h1 = HistoryItem() h1.request = request res.set_id(_id) h1.response = res h1.save() x = xml_file() finding = Finding(x._get_jinja2_env(), vuln) xml = finding.to_string() self.assertNotIn('such as <, & and > which MUST', xml) self.assertIn('such as <, & and > which MUST', xml) self.assertValidXML(xml)
def test_info_set_keep_uniq_id(self): # # Create a new InfoSet, load it from the KB, confirm that it has # the same uniq_id # vuln = MockVuln(name='Foos') info_set_a, created = kb.append_uniq_group( 'a', 'b', vuln, group_klass=MockInfoSetNames) self.assertTrue(created) info_set_b = kb.get('a', 'b')[0] self.assertEqual(info_set_a.get_uniq_id(), info_set_b.get_uniq_id()) # # Change the InfoSet a little bit by adding a new Info. That should # change the uniq_id # vuln = MockVuln(name='Foos') _, created = kb.append_uniq_group('a', 'b', vuln, group_klass=MockInfoSetNames) self.assertFalse(created) info_set_b = kb.get('a', 'b')[0] self.assertNotEqual(info_set_a.get_uniq_id(), info_set_b.get_uniq_id())
def start(self, tag, attrib): """ <vulnerability id="[87]" method="GET" name="Cross site scripting vulnerability" plugin="xss" severity="Medium" url="http://moth/w3af/audit/xss/simple_xss_no_script_2.php" var="text"> """ if tag == 'vulnerability': name = attrib['name'] plugin = attrib['plugin'] v = MockVuln(name, None, 'High', 1, plugin) v.set_url(URL(attrib['url'])) self.vulns.append(v) # <body content-encoding="base64"> elif tag == 'body': content_encoding = attrib['content-encoding'] assert content_encoding == 'base64' self._inside_body = True elif tag == 'http-response': self._inside_response = True
def test_render_attr_with_special_chars(self): _id = 2 name = 'A long description with special characters: <&">' vuln = MockVuln(_id=_id) vuln.set_name(name) url = URL('http://w3af.com/a/b/c.php') hdr = Headers([('User-Agent', 'w3af')]) request = HTTPRequest(url, data='a=1') request.set_headers(hdr) hdr = Headers([('Content-Type', 'text/html')]) res = HTTPResponse(200, '<html>', hdr, url, url) h1 = HistoryItem() h1.request = request res.set_id(_id) h1.response = res h1.save() x = xml_file() finding = Finding(x._get_jinja2_env(), vuln) xml = finding.to_string() self.assertNotIn(name, xml) self.assertIn('A long description with special characters: <&">', xml) self.assertValidXML(xml)
def test_render_with_unicode_control_chars(self): _id = 2 desc = ('This is a long description that contains some special' ' unicode control characters such as \f and \x09') vuln = MockVuln(_id=_id) vuln.set_desc(desc) url = URL('http://w3af.com/a/b/c.php') hdr = Headers([('User-Agent', 'w3af')]) request = HTTPRequest(url, data='a=1') request.set_headers(hdr) hdr = Headers([('Content-Type', 'text/html')]) res = HTTPResponse(200, '<html>', hdr, url, url) h1 = HistoryItem() h1.request = request res.set_id(_id) h1.response = res h1.save() x = xml_file() finding = Finding(x._get_jinja2_env(), vuln) xml = finding.to_string() self.assertNotIn('unicode control characters such as \f and \x09', xml) self.assertIn('unicode control characters such as <character code="000c"/> and <character code="0009"/>', xml) self.assertValidXML(xml)
def test_render_with_unicode_control_chars(self): _id = 2 desc = ('This is a long description that contains some special' ' unicode control characters such as \f and \x09') vuln = MockVuln(_id=_id) vuln.set_desc(desc) url = URL('http://w3af.com/a/b/c.php') hdr = Headers([('User-Agent', 'w3af')]) request = HTTPRequest(url, data='a=1') request.set_headers(hdr) hdr = Headers([('Content-Type', 'text/html')]) res = HTTPResponse(200, '<html>', hdr, url, url) h1 = HistoryItem() h1.request = request res.set_id(_id) h1.response = res h1.save() x = xml_file() finding = Finding(x._get_jinja2_env(), vuln) xml = finding.to_string() self.assertNotIn('unicode control characters such as \f and \x09', xml) self.assertIn( 'unicode control characters such as <character code="000c"/> and <character code="0009"/>', xml) self.assertValidXML(xml)
def test_render_attr_with_special_chars(self): _id = 2 name = 'A long description with special characters: <&">' vuln = MockVuln(_id=_id) vuln.set_name(name) url = URL('http://w3af.com/a/b/c.php') hdr = Headers([('User-Agent', 'w3af')]) request = HTTPRequest(url, data='a=1') request.set_headers(hdr) hdr = Headers([('Content-Type', 'text/html')]) res = HTTPResponse(200, '<html>', hdr, url, url) h1 = HistoryItem() h1.request = request res.set_id(_id) h1.response = res h1.save() x = xml_file() finding = Finding(x._get_jinja2_env(), vuln) xml = finding.to_string() self.assertNotIn(name, xml) self.assertIn( 'A long description with special characters: <&">', xml) self.assertValidXML(xml)
def test_get_one(self): vuln = MockVuln() kb.append('a', 'b', vuln) kb_vuln = kb.get_one('a', 'b') #pylint: disable=E1103 self.assertEqual(kb_vuln.get_uniq_id(), vuln.get_uniq_id()) self.assertEqual(kb_vuln, vuln)
def test_append_uniq_group_empty_address(self): vuln = MockVuln() info_set, created = kb.append_uniq_group('a', 'b', vuln) self.assertIsInstance(info_set, InfoSet) self.assertTrue(created) self.assertEqual(info_set.get_urls(), [vuln.get_url()]) self.assertEqual(info_set.get_name(), vuln.get_name()) self.assertEqual(info_set.get_id(), vuln.get_id()) self.assertEqual(info_set.get_plugin_name(), vuln.get_plugin_name())
def test_render_unicode_bytestring(self): vuln = MockVuln(name='á') vuln.set_id([]) x = xml_file() finding = Finding(x._get_jinja2_env(), vuln) xml = finding.to_string() self.assertIn(u'á', xml) self.assertValidXML(xml)
def _from_json_get_vulns(self, filename): json_data = json.load(open(filename, 'r')) vulns = [] for finding in json_data['items']: v = MockVuln(finding['Name'], None, 'High', 1, 'sqli') v.set_url(URL(finding['URL'])) vulns.append(v) return vulns
def test_render_url_special_chars(self): self.maxDiff = None _id = 2 vuln = MockVuln(_id=_id) url = URL( u'https://w3af.com/._basebind/node_modules/lodash._basecreate/' u'LICENSE.txt\x00=ڞ') hdr = Headers([('User-Agent', 'w3af')]) request = HTTPRequest(url, data='a=1') request.set_headers(hdr) vuln.set_uri(url) hdr = Headers([('Content-Type', 'text/html')]) res = HTTPResponse(200, '<html>', hdr, url, url) h1 = HistoryItem() h1.request = request res.set_id(_id) h1.response = res h1.save() x = xml_file() finding = Finding(x._get_jinja2_env(), vuln) xml = finding.to_string() expected = ( u'<vulnerability id="[2]" method="GET" name="TestCase" plugin="plugin_name" severity="High" url="https://w3af.com/._basebind/node_modules/lodash._basecreate/LICENSE.txt<character code="0000"/>=\u069e" var="None">\n' u' <description>Foo bar spam eggsFoo bar spam eggsFoo bar spam eggsFoo bar spam eggsFoo bar spam eggsFoo bar spam eggsFoo bar spam eggsFoo bar spam eggsFoo bar spam eggsFoo bar spam eggs</description>\n\n\n' u' <http-transactions>\n' u' <http-transaction id="2">\n\n' u' <http-request>\n' u' <status>POST https://w3af.com/._basebind/node_modules/lodash._basecreate/LICENSE.txt%00=%DA%9E HTTP/1.1</status>\n' u' <headers>\n' u' <header field="User-agent" content="w3af" />\n' u' </headers>\n' u' <body content-encoding="base64">YT0x\n</body>\n' u' </http-request>\n\n' u' <http-response>\n' u' <status>HTTP/1.1 200 OK</status>\n' u' <headers>\n' u' <header field="Content-Type" content="text/html" />\n' u' </headers>\n' u' <body content-encoding="base64">PGh0bWw+\n</body>\n' u' </http-response>\n\n' u'</http-transaction>\n' u' </http-transactions>\n' u'</vulnerability>') self.assertEqual(xml, expected) self.assertValidXML(xml)
def test_update_exception(self): vuln = MockVuln() kb.append('a', 'b', vuln) original_id = vuln.get_uniq_id() # Cause error by changing vuln uniq_id update_vuln = vuln update_vuln._uniq_id = str(uuid.uuid4()) modified_id = vuln.get_uniq_id() self.assertNotEqual(original_id, modified_id) self.assertRaises(DBException, kb.update, vuln, update_vuln)
def test_update_exception(self): vuln = MockVuln() kb.append('a', 'b', vuln) original_id = vuln.get_uniq_id() # Cause error by changing vuln uniq_id update_vuln = vuln update_vuln.set_name('a') modified_id = vuln.get_uniq_id() self.assertNotEqual(original_id, modified_id) self.assertRaises(DBException, kb.update, vuln, update_vuln)
def _from_html_get_vulns(self): vuln_url_re = re.compile('<li>Vulnerable URL: <a href="(.*?)">') vulns = [] for line in file(self.OUTPUT_FILE): mo = vuln_url_re.search(line) if mo: url = URL(mo.group(1)) v = MockVuln('TestCase', None, 'High', 1, 'plugin') v.set_url(url) vulns.append(v) return vulns
def _from_html_get_vulns(self): vuln_url_re = re.compile('<b>URL:</b> (.*?)<br />') vulns = [] for line in file(self.OUTPUT_FILE): mo = vuln_url_re.search(line) if mo: url = URL(mo.group(1)) v = MockVuln('TestCase', None, 'High', 1, 'plugin') v.set_url(url) vulns.append(v) return vulns
def test_help_contents(self): shell = ReadShell(MockVuln(), None, None) _help = shell.help(None) self.assertNotIn('execute', _help) self.assertNotIn('upload', _help) self.assertIn('read', _help)
def test_pickleable_vuln(self): original_vuln = MockVuln() kb.append('a', 'b', original_vuln) unpickled_vuln = kb.get('a', 'b')[0] self.assertEqual(original_vuln, unpickled_vuln)
def test_kb_list_shells_rfi_port_scan_2181(self): """ :see: https://github.com/andresriancho/w3af/issues/2181 """ w3af_core = w3afCore() vuln = MockVuln() url = URL('http://moth/?a=1') freq = FuzzableRequest(url) exploit_mutant = QSMutant.create_mutants(freq, [''], [], False, {})[0] shell = PortScanShell(vuln, w3af_core.uri_opener, w3af_core.worker_pool, exploit_mutant) kb.append('a', 'b', shell) shells = kb.get_all_shells(w3af_core=w3af_core) self.assertEqual(len(shells), 1) unpickled_shell = shells[0] self.assertEqual(shell, unpickled_shell) self.assertIs(unpickled_shell._uri_opener, w3af_core.uri_opener) self.assertIs(unpickled_shell.worker_pool, w3af_core.worker_pool) self.assertEqual(unpickled_shell._exploit_mutant, exploit_mutant) w3af_core.quit()
def test_kb_list_shells_xpath_2181(self): """ :see: https://github.com/andresriancho/w3af/issues/2181 """ w3af_core = w3afCore() vuln = MockVuln() str_delim = '&' true_cond = '' use_difflib = False is_error_response = IsErrorResponse(vuln, w3af_core.uri_opener, use_difflib) shell = XPathReader(vuln, w3af_core.uri_opener, w3af_core.worker_pool, str_delim, true_cond, is_error_response) kb.append('a', 'b', shell) shells = kb.get_all_shells(w3af_core=w3af_core) self.assertEqual(len(shells), 1) unpickled_shell = shells[0] self.assertEqual(shell, unpickled_shell) self.assertIs(unpickled_shell._uri_opener, w3af_core.uri_opener) self.assertIs(unpickled_shell.worker_pool, w3af_core.worker_pool) self.assertEqual(unpickled_shell.STR_DELIM, shell.STR_DELIM) self.assertEqual(unpickled_shell.TRUE_COND, shell.TRUE_COND) self.assertEqual(unpickled_shell.is_error_resp.use_difflib, use_difflib) self.assertEqual(unpickled_shell.is_error_resp.url_opener, w3af_core.uri_opener) w3af_core.quit()
def _from_txt_get_vulns(self): file_vulns = [] vuln_regex = 'SQL injection in a .*? was found at: "(.*?)"' \ ', using HTTP method (.*?). The sent .*?data was: "(.*?)"' vuln_re = re.compile(vuln_regex) for line in file(self.OUTPUT_FILE): mo = vuln_re.search(line) if mo: v = MockVuln('TestCase', None, 'High', 1, 'plugin') v.set_url(URL(mo.group(1))) v.set_method(mo.group(2)) file_vulns.append(v) return file_vulns
def test_append_uniq_group_filter_func_specific(self): vuln1 = MockVuln(name='Foos') vuln2 = MockVuln(name='Bars') vuln3 = MockVuln(name='Foos', _id=42) kb.append_uniq_group('a', 'b', vuln1, group_klass=MockInfoSetNames) kb.append_uniq_group('a', 'b', vuln2, group_klass=MockInfoSetNames) kb.append_uniq_group('a', 'b', vuln3, group_klass=MockInfoSetNames) raw_data = kb.get('a', 'b') self.assertEqual(len(raw_data), 2) self.assertIsInstance(raw_data[0], InfoSet) self.assertIsInstance(raw_data[1], InfoSet) self.assertEqual(raw_data[0].get_name(), 'Foos') self.assertEqual(len(raw_data[0].infos), 2) self.assertEqual(raw_data[0].infos[1].get_id(), [42]) self.assertEqual(raw_data[1].first_info.get_name(), 'Bars')
def test_append_uniq_group_no_match_filter_func(self): vuln1 = MockVuln(name='Foos') vuln2 = MockVuln(name='Bars') kb.append_uniq_group('a', 'b', vuln1, group_klass=MockInfoSetFalse) info_set, created = kb.append_uniq_group('a', 'b', vuln2, group_klass=MockInfoSetFalse) self.assertIsInstance(info_set, InfoSet) self.assertTrue(created) self.assertEqual(len(info_set.infos), 1) raw_data = kb.get('a', 'b') self.assertEqual(len(raw_data), 2) self.assertIsInstance(raw_data[0], InfoSet) self.assertIsInstance(raw_data[1], InfoSet) self.assertEqual(raw_data[0].first_info.get_name(), 'Foos') self.assertEqual(raw_data[1].first_info.get_name(), 'Bars')
def test_all_of_info_vuln(self): i1 = MockInfo() i2 = MockInfo() v1 = MockVuln() v2 = MockVuln() iset = InfoSet([i2]) vset = InfoSet([v2]) kb.append('a', 'b', i1) kb.append('w', 'z', iset) kb.append('x', 'y', v1) kb.append('4', '2', vset) self.assertEqual(kb.get_all_vulns(), [v1, vset]) self.assertEqual(kb.get_all_infos(), [i1, iset]) self.assertEqual(kb.get_all_findings(), [i1, iset, v1, vset])
def test_append_uniq_group_match_filter_func(self): vuln = MockVuln() kb.append_uniq_group('a', 'b', vuln, group_klass=MockInfoSetTrue) info_set, created = kb.append_uniq_group('a', 'b', vuln, group_klass=MockInfoSetTrue) self.assertFalse(created) self.assertIsInstance(info_set, InfoSet) self.assertEqual(len(info_set.infos), 2)
def test_help_format(self): shell = ExecShell(MockVuln(), None, None) _help = shell.help(None) self.assertFalse(_help.startswith(' ')) self.assertIn(' help', _help) # Note that I add an extra space self.assertNotIn(' help', _help)
def test_update_vuln(self): vuln = MockVuln() kb.append('a', 'b', vuln) update_vuln = copy.deepcopy(vuln) update_vuln.set_name('a') update_uniq_id = update_vuln.get_uniq_id() kb.update(vuln, update_vuln) self.assertNotEqual(update_vuln, vuln) self.assertEqual(update_vuln, kb.get_by_uniq_id(update_uniq_id))
def start(self, tag, attrib): """ <vulnerability id="[87]" method="GET" name="Cross site scripting vulnerability" plugin="xss" severity="Medium" url="http://moth/w3af/audit/xss/simple_xss_no_script_2.php" var="text"> """ if tag == "vulnerability": name = attrib["name"] plugin = attrib["plugin"] v = MockVuln(name, None, "High", 1, plugin) v.set_url(URL(attrib["url"])) self.vulns.append(v) # <body content-encoding="text"> elif tag == "body": content_encoding = attrib["content-encoding"] assert content_encoding == "text" self._inside_body = True
def multi_append(): for i in xrange(InfoSet.MAX_INFO_INSTANCES * 2): vuln = MockVuln() kb.append_uniq_group('a', 'b', vuln, group_klass=MockInfoSetTrue) info_set_list = kb.get('a', 'b') self.assertEqual(len(info_set_list), 1) info_set = info_set_list[0] self.assertEqual(len(info_set.infos), InfoSet.MAX_INFO_INSTANCES) return True
def test_all_of_info_exclude_ids(self): i1 = MockInfo() i2 = MockInfo() v1 = MockVuln() v2 = MockVuln() iset = InfoSet([i2]) vset = InfoSet([v2]) kb.append('a', 'b', i1) kb.append('w', 'z', iset) kb.append('x', 'y', v1) kb.append('4', '2', vset) all_findings = kb.get_all_findings() all_findings_except_v1 = kb.get_all_findings(exclude_ids=(v1.get_uniq_id(),)) all_findings_except_v1_v2 = kb.get_all_findings(exclude_ids=(v1.get_uniq_id(), vset.get_uniq_id())) self.assertEqual(all_findings, [i1, iset, v1, vset]) self.assertEqual(all_findings_except_v1, [i1, iset, vset]) self.assertEqual(all_findings_except_v1_v2, [i1, iset])
def test_append_uniq_group_filter_func_attribute_match(self): vuln1 = MockVuln(name='Foos') vuln1['tag'] = 'foo' vuln2 = MockVuln(name='Bars') vuln2['tag'] = 'bar' vuln3 = MockVuln(_id=42) vuln3['tag'] = 'foo' kb.append_uniq_group('a', 'b', vuln1, group_klass=MockInfoSetITag) kb.append_uniq_group('a', 'b', vuln2, group_klass=MockInfoSetITag) kb.append_uniq_group('a', 'b', vuln3, group_klass=MockInfoSetITag) raw_data = kb.get('a', 'b') self.assertEqual(len(raw_data), 2) self.assertIsInstance(raw_data[0], InfoSet) self.assertIsInstance(raw_data[1], InfoSet) self.assertEqual(raw_data[0].get_name(), 'Foos') self.assertEqual(len(raw_data[0].infos), 2) self.assertEqual(raw_data[0].infos[1].get_id(), [42]) self.assertEqual(raw_data[1].first_info.get_name(), 'Bars')
def test_render_simple(self): _id = 2 vuln = MockVuln(_id=_id) url = URL('http://w3af.com/a/b/c.php') hdr = Headers([('User-Agent', 'w3af')]) request = HTTPRequest(url, data='a=1') request.set_headers(hdr) hdr = Headers([('Content-Type', 'text/html')]) res = HTTPResponse(200, '<html>', hdr, url, url) h1 = HistoryItem() h1.request = request res.set_id(_id) h1.response = res h1.save() x = xml_file() finding = Finding(x._get_jinja2_env(), vuln) xml = finding.to_string() expected = ( u'<vulnerability id="[2]" method="GET" name="TestCase" plugin="plugin_name" severity="High" url="None" var="None">\n' u' <description>Foo bar spam eggsFoo bar spam eggsFoo bar spam eggsFoo bar spam eggsFoo bar spam eggsFoo bar spam eggsFoo bar spam eggsFoo bar spam eggsFoo bar spam eggsFoo bar spam eggs</description>\n\n\n' u' <http-transactions>\n' u' <http-transaction id="2">\n\n' u' <http-request>\n' u' <status>POST http://w3af.com/a/b/c.php HTTP/1.1</status>\n' u' <headers>\n' u' <header field="User-agent" content="w3af" />\n' u' </headers>\n' u' <body content-encoding="base64">YT0x\n</body>\n' u' </http-request>\n\n' u' <http-response>\n' u' <status>HTTP/1.1 200 OK</status>\n' u' <headers>\n' u' <header field="Content-Type" content="text/html" />\n' u' </headers>\n' u' <body content-encoding="base64">PGh0bWw+\n</body>\n' u' </http-response>\n\n' u'</http-transaction>\n' u' </http-transactions>\n' u'</vulnerability>') self.assertEqual(xml, expected) self.assertValidXML(xml)
def test_pickleable_shells(self): pool = Pool(1) xurllib = ExtendedUrllib() original_shell = Shell(MockVuln(), xurllib, pool) kb.append('a', 'b', original_shell) unpickled_shell = kb.get('a', 'b')[0] self.assertEqual(original_shell, unpickled_shell) self.assertEqual(unpickled_shell.worker_pool, None) self.assertEqual(unpickled_shell._uri_opener, None) pool.terminate() pool.join() xurllib.end()
def test_pickleable_shells_get_all(self): class FakeCore(object): worker_pool = Pool(1) uri_opener = ExtendedUrllib() core = FakeCore() original_shell = Shell(MockVuln(), core.uri_opener, core.worker_pool) kb.append('a', 'b', original_shell) unpickled_shell = list(kb.get_all_shells(core))[0] self.assertEqual(original_shell, unpickled_shell) self.assertEqual(unpickled_shell.worker_pool, core.worker_pool) self.assertEqual(unpickled_shell._uri_opener, core.uri_opener) core.worker_pool.terminate() core.worker_pool.join() core.uri_opener.end()
def test_info_set_keep_uniq_id_after_max_info_instances(self): # # Create one InfoSet, add MAX_INFO_INSTANCES, assert that the ID is not # changed afterwards # vuln = MockVuln(name='Foos') for _ in xrange(MockInfoSetNames.MAX_INFO_INSTANCES + 1): kb.append_uniq_group('a', 'b', vuln, group_klass=MockInfoSetNames) info_set_before = kb.get('a', 'b')[0] # Now some rounds of testing for _ in xrange(5): info_set_after, _ = kb.append_uniq_group( 'a', 'b', vuln, group_klass=MockInfoSetNames) self.assertEqual(info_set_before.get_uniq_id(), info_set_after.get_uniq_id())
def test_kb_list_shells_file_upload_2181(self): """ :see: https://github.com/andresriancho/w3af/issues/2181 """ w3af_core = w3afCore() exploit_url = URL('http://w3af.org/') shell = FileUploadShell(MockVuln(), w3af_core.uri_opener, w3af_core.worker_pool, exploit_url) kb.append('a', 'b', shell) shells = kb.get_all_shells(w3af_core=w3af_core) self.assertEqual(len(shells), 1) unpickled_shell = shells[0] self.assertEqual(shell, unpickled_shell) self.assertIs(unpickled_shell._uri_opener, w3af_core.uri_opener) self.assertIs(unpickled_shell.worker_pool, w3af_core.worker_pool) self.assertEqual(unpickled_shell._exploit_url, shell._exploit_url) w3af_core.quit()
def test_cache_works_as_expected(self): # # Cache starts empty # cache = FindingsCache() self.assertEquals(cache.list(), []) # # Create two vulnerabilities with their HTTP requests and responses # _id = 1 name = 'I have a name' vuln1 = MockVuln(_id=_id) vuln1.set_name(name) url = URL('http://w3af.com/a/b/c.php') hdr = Headers([('User-Agent', 'w3af')]) request = HTTPRequest(url, data='a=1') request.set_headers(hdr) hdr = Headers([('Content-Type', 'text/html')]) res = HTTPResponse(200, '<html>', hdr, url, url) h1 = HistoryItem() h1.request = request res.set_id(_id) h1.response = res h1.save() _id = 2 name = 'Just a name' vuln2 = MockVuln(_id=_id) vuln2.set_name(name) url = URL('http://w3af.com/a/b/c.php') hdr = Headers([('User-Agent', 'w3af')]) request = HTTPRequest(url, data='a=1') request.set_headers(hdr) hdr = Headers([('Content-Type', 'text/html')]) res = HTTPResponse(200, '<html>', hdr, url, url) h2 = HistoryItem() h2.request = request res.set_id(_id) h2.response = res h2.save() # # Save one vulnerability to the KB and call the cache-user # kb.kb.append('a', 'b', vuln1) x = xml_file() list(x.findings()) self.assertEquals(cache.list(), [vuln1.get_uniq_id()]) # # Save another vulnerability to the KB and call the cache-user # kb.kb.append('a', 'c', vuln2) list(x.findings()) expected = {vuln1.get_uniq_id(), vuln2.get_uniq_id()} self.assertEquals(set(cache.list()), expected) # # Remove one vulnerability and see how it is removed from the cache # kb.kb.raw_write('a', 'c', 'noop') list(x.findings()) expected = {vuln1.get_uniq_id()} self.assertEquals(set(cache.list()), expected)