def test_endpoint_for_secure_headers(httpEndpoint): # Setup the server to scan and ensure it is online/reachable hostname = httpEndpoint.get_endpoint_url() try: server_info = ServerConnectivityInfo(hostname=hostname) server_info.test_connectivity_to_server() except ServerConnectivityError as e: # Could not establish an SSL connection to the server raise RuntimeError('Error when connecting to {}: {}'.format( hostname, e.error_msg)) hpkp_report_only = False # Perform the SSL handshake ssl_connection = server_info.get_preconfigured_ssl_connection() ssl_connection.connect() certificate_chain = [ cryptography.x509.load_pem_x509_certificate( x509_cert.as_pem().encode('ascii'), backend=default_backend()) for x509_cert in ssl_connection.ssl_client.get_peer_cert_chain() ] # Send an HTTP GET request to the server ssl_connection.write( HttpRequestGenerator.get_request(host=server_info.hostname)) http_resp = HttpResponseParser.parse(ssl_connection) ssl_connection.close() if http_resp.version == 9: # HTTP 0.9 => Probably not an HTTP response raise ValueError('Server did not return an HTTP response') else: hsts_header = http_resp.getheader('strict-transport-security', None) x_frame_options_header = http_resp.getheader('x-frame-options', None) x_xss_protection_header = http_resp.getheader('x-xss-protection', None) content_security_policy_header = http_resp.getheader( 'Content-Security-Policy', None) content_security_policy_report_only_header = http_resp.getheader( 'content-security-policy-report-only', None) hpkp_header = http_resp.getheader('public-key-pins', None) expect_ct_header = http_resp.getheader('expect-ct', None) if hpkp_header is None: hpkp_report_only = True hpkp_header = http_resp.getheader('public-key-pins-report-only', None) # We do not follow redirections because the security headers must be set on the first page according to # https://hstspreload.appspot.com/: # "If you are serving an additional redirect from your HTTPS site, that redirect must still have the HSTS # header (rather than the page it redirects to)." if hsts_header is not None: httpEndpoint.set_hsts_enabled(True) if "includeSubDomains".lower() not in hsts_header.lower(): httpEndpoint.set_hsts_issues("includeSubDomains is not set.") if "max-age".lower() not in hsts_header.lower(): issueValue = httpEndpoint.get_hsts_issues() issueValue += "max-age is not set." httpEndpoint.set_hsts_issues(issueValue) if x_xss_protection_header is not None: httpEndpoint.set_x_xss_protection_enabled(True) if "mode=block".lower() not in x_xss_protection_header.lower(): httpEndpoint.set_x_xss_protection_issues("mode=block is not set.") if x_frame_options_header is not None: httpEndpoint.set_x_frame_options_enabled(True) if "SAMEORIGIN".lower() not in x_frame_options_header.lower(): httpEndpoint.set_x_frame_options_issues( "SAMEORIGIN value is not set") if content_security_policy_header is not None: httpEndpoint.set_csp_enabled(True) #print(hsts_header) #print(x_frame_options_header) #print(x_xss_protection_header) print(content_security_policy_header) #print(content_security_policy_report_only_header) #print(http_resp.getheaders()) return httpEndpoint