def test_find_vulns_case03(self): """ Test case in which we set vulnerables policies for "sandbox","reflected-xss" directives using valid values. """ header_value = "sandbox allow-* allow-forms allow-same-origin " \ "allow-scripts allow-top-navigation;"\ "reflected-xss allow;" hrds = {CSP_HEADER_W3C: header_value}.items() csp_headers = Headers(hrds) http_response = HTTPResponse(200, '', csp_headers, self.url, self.url) vulns = find_vulns(http_response) self.assertEqual(len(vulns), 2) #>>>"sandbox" self.assertEqual(len(vulns[CSP_DIRECTIVE_SANDBOX]), 2) warn_msg = "Directive 'sandbox' apply no restrictions." self.assertTrue(vulns[CSP_DIRECTIVE_SANDBOX][0].desc, warn_msg) self.assertTrue(vulns[CSP_DIRECTIVE_SANDBOX][1].desc, warn_msg) #>>>"reflected-xss" self.assertEqual(len(vulns[CSP_DIRECTIVE_XSS]), 1) warn_msg = "Directive 'reflected-xss' instruct user agent to "\ "disable its active protections against reflected XSS." self.assertTrue(self._vuln_exists(warn_msg, vulns[CSP_DIRECTIVE_XSS]))
def test_find_vulns_case02(self): """ Test case in which we set vulnerables policies for "sandbox", "script-nonce","plugin-types","reflected-xss" directives using invalid values. """ header_value = "sandbox allow-invalid; script-nonce aaa,bbb;"\ "plugin-types app/titi application/pdf; reflected-xss disallow;" hrds = {CSP_HEADER_W3C: header_value}.items() csp_headers = Headers(hrds) http_response = HTTPResponse(200, '', csp_headers, self.url, self.url) vulns = find_vulns(http_response) self.assertEqual(len(vulns), 4) #>>>"sandbox" self.assertEqual(len(vulns[CSP_DIRECTIVE_SANDBOX]), 1) warn_msg = "Directive 'sandbox' specify invalid value: 'allow-invalid'." self.assertTrue(self._vuln_exists(warn_msg, vulns[CSP_DIRECTIVE_SANDBOX])) #>>>"script-nonce" self.assertEqual(len(vulns[CSP_DIRECTIVE_SCRIPT_NONCE]), 1) warn_msg = "Directive 'script-nonce' is defined "\ "but nonce contains invalid character (','|';')." self.assertTrue(self._vuln_exists(warn_msg, vulns[CSP_DIRECTIVE_SCRIPT_NONCE])) #>>>"reflected-xss" self.assertEqual(len(vulns[CSP_DIRECTIVE_XSS]), 1) warn_msg = "Directive 'reflected-xss' specify invalid value: 'disallow'." self.assertTrue(self._vuln_exists(warn_msg, vulns[CSP_DIRECTIVE_XSS])) #>>>"plugins-types" self.assertEqual(len(vulns[CSP_DIRECTIVE_PLUGIN_TYPES]), 1) warn_msg = "Directive 'plugin-types' specify invalid mime type: 'app/titi'." self.assertTrue(self._vuln_exists(warn_msg, vulns[CSP_DIRECTIVE_PLUGIN_TYPES]))
def grep(self, request, response): """ Perform search on current HTTP request/response exchange. Store information about vulns for further global processing. @param request: HTTP request @param response: HTTP response """ # Check that current URL has not been already analyzed response_url = response.get_url().uri2url() if response_url in self._urls: return self._urls.append(response_url) # Search issues using dedicated module csp_vulns = find_vulns(response) # Analyze issue list if len(csp_vulns) > 0: vuln_store_item = DiskCSPVulnStoreItem(response_url, response.id, csp_vulns) self._vulns.append(vuln_store_item) # Increment the vulnerabilities counter for csp_directive_name in csp_vulns: self._total_count += len(csp_vulns[csp_directive_name])
def grep(self, request, response): """ Perform search on current HTTP request/response exchange. Store informations about vulns for further global processing. @param request: HTTP request @param response: HTTP response """ #Check that current URL has not been already analyzed response_url = str(response.get_url().uri2url()) if response_url in self._urls: return else: self._urls.append(response_url) #Search issues using dedicated module csp_vulns = find_vulns(response) #Analyze issue list if len(csp_vulns) > 0: vuln_store_item = DiskCSPVulnStoreItem(response_url, response.id, csp_vulns) self._vulns.append(vuln_store_item) #Increment the vulnerabilities counter for csp_directive_name in csp_vulns: self._total_count += len(csp_vulns[csp_directive_name])
def test_find_vulns_case04(self): """ Test case in which we configure correctly policies for all directives. """ header_value = "default-src 'self';script-src 'self';object-src 'self';" \ "style-src 'self';img-src 'self';media-src 'self';" \ "frame-src 'self';font-src 'self';sandbox;" \ "form-action '/myCtx/act';connect-src 'self';"\ "plugin-types application/pdf;reflected-xss filter;"\ "script-nonce AABBCCDDEE;" hrds = {CSP_HEADER_W3C: header_value}.items() csp_headers = Headers(hrds) http_response = HTTPResponse(200, '', csp_headers, self.url, self.url) vulns = find_vulns(http_response) self.assertEqual(len(vulns), 0)
def test_find_vulns_case05(self): """ Test case in which we misspell somes policies. """ header_value = "defauld-src 'self';script-src 'self';object-src 'self';" \ "style-src 'self';image-src 'self';media-src 'self';" \ "frame-src 'self';font-src 'self';sandbox;" \ "form-src '/myCtx/act';connect-src 'self';"\ "plugin-types application/pdf;reflected-xss filter;"\ "script-nonce AABBCCDDEE;" hrds = {CSP_HEADER_W3C: header_value}.items() csp_headers = Headers(hrds) http_response = HTTPResponse(200, '', csp_headers, self.url, self.url) vulns = find_vulns(http_response) self.assertEqual(len(vulns), 1) self.assertEqual(len(vulns[CSP_MISSPELLED_DIRECTIVES]), 1) warn_msg = "Some directives are misspelled: "\ "defauld-src, image-src, form-src" self.assertTrue(self._vuln_exists(warn_msg, vulns[CSP_MISSPELLED_DIRECTIVES]))
def audit(self, freq, orig_response): """ :param freq: A FuzzableRequest :param orig_resp: The HTTP response we get from sending the freq :return: None, all results are saved in the kb. """ headers = orig_response.get_lower_case_headers() csp_value = headers.get('content-security-policy', None) if csp_value is None: desc = 'Host has no HTTP "Content-Security-Policy" header. Add it correctly and you will fix that issue.' v = Vuln('Omitted server header', desc, severity.MEDIUM, orig_response.id, self.get_name()) v.set_url(orig_response.get_url()) self.kb_append(self, 'wg_csp', v) else: # Search issues using dedicated module csp_vulns = find_vulns(orig_response) for csp_directive_name in csp_vulns: csp_vuln = csp_vulns[csp_directive_name][0] v = Vuln('Server header', csp_vuln.desc, csp_vuln.severity, orig_response.id, self.get_name()) v.set_url(orig_response.get_url()) self.kb_append(self, 'wg_csp', v)
def test_find_vulns_case01(self): """ Test case in which we set vulnerables policies using "*" as source for all directives that allow this value. """ header_value = "default-src '*';script-src '*';object-src '*';" \ "style-src '*';img-src '*';media-src '*';" \ "frame-src '*';font-src '*';" \ "form-action '*';connect-src '*';plugin-types '*';" hrds = {CSP_HEADER_W3C: header_value}.items() csp_headers = Headers(hrds) http_response = HTTPResponse(200, '', csp_headers, self.url, self.url) vulns = find_vulns(http_response) self.assertEqual(len(vulns), 11) #>>>"default-src" self.assertEqual(len(vulns[CSP_DIRECTIVE_DEFAULT]), 1) self.assertTrue(self._vuln_exists("Directive 'default-src' allows all sources.", vulns[CSP_DIRECTIVE_DEFAULT])) #>>>"script-src" self.assertEqual(len(vulns[CSP_DIRECTIVE_SCRIPT]), 2) self.assertTrue(self._vuln_exists("Directive 'script-src' allows all javascript sources.", vulns[CSP_DIRECTIVE_SCRIPT])) warn_msg = "Directive 'script-src' is defined but no directive " \ "'script-nonce' is defined to protect javascript resources." self.assertTrue(self._vuln_exists(warn_msg, vulns[CSP_DIRECTIVE_SCRIPT])) #>>>"object-src" self.assertEqual(len(vulns[CSP_DIRECTIVE_OBJECT]), 1) self.assertTrue(self._vuln_exists("Directive 'object-src' allows all plugin sources.", vulns[CSP_DIRECTIVE_OBJECT])) #>>>"style-src" self.assertEqual(len(vulns[CSP_DIRECTIVE_STYLE]), 1) self.assertTrue(self._vuln_exists("Directive 'style-src' allows all CSS sources.", vulns[CSP_DIRECTIVE_STYLE])) #>>>"img-src" self.assertEqual(len(vulns[CSP_DIRECTIVE_IMAGE]), 1) self.assertTrue(self._vuln_exists("Directive 'img-src' allows all image sources.", vulns[CSP_DIRECTIVE_IMAGE])) #>>>"media-src" self.assertEqual(len(vulns[CSP_DIRECTIVE_MEDIA]), 1) self.assertTrue(self._vuln_exists("Directive 'media-src' allows all audio/video sources.", vulns[CSP_DIRECTIVE_MEDIA])) #>>>"frame-src" self.assertEqual(len(vulns[CSP_DIRECTIVE_FRAME]), 2) self.assertTrue(self._vuln_exists("Directive 'frame-src' allows all sources.", vulns[CSP_DIRECTIVE_FRAME])) warn_msg = "Directive 'frame-src' is defined but no directive " \ "'sandbox' is defined to protect resources. Perhaps sandboxing " \ "is defined at html attribute level ?" self.assertTrue(self._vuln_exists(warn_msg, vulns[CSP_DIRECTIVE_FRAME])) #>>>"font-src" self.assertEqual(len(vulns[CSP_DIRECTIVE_FONT]), 1) self.assertTrue(self._vuln_exists("Directive 'font-src' allows all font sources.", vulns[CSP_DIRECTIVE_FONT])) #>>>"connect-src" self.assertEqual(len(vulns[CSP_DIRECTIVE_CONNECTION]), 1) self.assertTrue(self._vuln_exists("Directive 'connect-src' allows all connection sources.", vulns[CSP_DIRECTIVE_CONNECTION])) #>>>"form-action" self.assertEqual(len(vulns[CSP_DIRECTIVE_FORM]), 1) self.assertTrue(self._vuln_exists("Directive 'form-action' allows all action target.", vulns[CSP_DIRECTIVE_FORM])) #>>>"plugin-types" self.assertEqual(len(vulns[CSP_DIRECTIVE_PLUGIN_TYPES]), 1) self.assertTrue(self._vuln_exists("Directive 'plugin-types' allows all plugins types.", vulns[CSP_DIRECTIVE_PLUGIN_TYPES]))