diff options
Diffstat (limited to 'test/haketilo_test/unit')
-rw-r--r-- | test/haketilo_test/unit/test_policy_deciding.py | 61 | ||||
-rw-r--r-- | test/haketilo_test/unit/test_policy_enforcing.py | 4 | ||||
-rw-r--r-- | test/haketilo_test/unit/test_webrequest.py | 4 | ||||
-rw-r--r-- | test/haketilo_test/unit/utils.py | 11 |
4 files changed, 53 insertions, 27 deletions
diff --git a/test/haketilo_test/unit/test_policy_deciding.py b/test/haketilo_test/unit/test_policy_deciding.py index 75b35ac..1be488f 100644 --- a/test/haketilo_test/unit/test_policy_deciding.py +++ b/test/haketilo_test/unit/test_policy_deciding.py @@ -23,19 +23,36 @@ import pytest from ..script_loader import load_script -csp_re = re.compile(r'^\S+\s+\S+;(?:\s+\S+\s+\S+;)*$') -rule_re = re.compile(r'^\s*(?P<src_kind>\S+)\s+(?P<allowed_origins>\S+)$') +csp_re = re.compile(r''' +^ +\S+(?:\s+\S+)+; # first directive +(?: + \s+\S+(?:\s+\S+)+; # subsequent directive +)* +$ +''', +re.VERBOSE) + +rule_re = re.compile(r''' +^ +\s* +(?P<src_kind>\S+) +\s+ +(?P<allowed_origins> + \S+(?:\s+\S+)* +) +$ +''', re.VERBOSE) + def parse_csp(csp): - ''' - Parsing of CSP string into a dict. A simplified format of CSP is assumed. - ''' + '''Parsing of CSP string into a dict.''' assert csp_re.match(csp) result = {} for rule in csp.split(';')[:-1]: match = rule_re.match(rule) - result[match.group('src_kind')] = match.group('allowed_origins') + result[match.group('src_kind')] = match.group('allowed_origins').split() return result @@ -78,10 +95,10 @@ def test_decide_policy(execute_in_page): for prop in ('mapping', 'payload', 'nonce', 'error'): assert prop not in policy assert parse_csp(policy['csp']) == { - 'prefetch-src': "'none'", - 'script-src-attr': "'none'", - 'script-src': "'none'", - 'script-src-elem': "'none'" + 'prefetch-src': ["'none'"], + 'script-src-attr': ["'none'"], + 'script-src': ["'none'", "'unsafe-eval'"], + 'script-src-elem': ["'none'"] } policy = execute_in_page( @@ -95,10 +112,10 @@ def test_decide_policy(execute_in_page): for prop in ('payload', 'nonce', 'error'): assert prop not in policy assert parse_csp(policy['csp']) == { - 'prefetch-src': "'none'", - 'script-src-attr': "'none'", - 'script-src': "'none'", - 'script-src-elem': "'none'" + 'prefetch-src': ["'none'"], + 'script-src-attr': ["'none'"], + 'script-src': ["'none'", "'unsafe-eval'"], + 'script-src-elem': ["'none'"] } policy = execute_in_page( @@ -114,10 +131,10 @@ def test_decide_policy(execute_in_page): assert policy['nonce'] == \ sha256('m1:res1:http://kno.wn/:abcd'.encode()).digest().hex() assert parse_csp(policy['csp']) == { - 'prefetch-src': f"'none'", - 'script-src-attr': f"'none'", - 'script-src': f"'nonce-{policy['nonce']}'", - 'script-src-elem': f"'nonce-{policy['nonce']}'" + 'prefetch-src': ["'none'"], + 'script-src-attr': ["'none'"], + 'script-src': [f"'nonce-{policy['nonce']}'", "'unsafe-eval'"], + 'script-src-elem': [f"'nonce-{policy['nonce']}'"] } policy = execute_in_page( @@ -128,8 +145,8 @@ def test_decide_policy(execute_in_page): for prop in ('mapping', 'payload', 'nonce'): assert prop not in policy assert parse_csp(policy['csp']) == { - 'prefetch-src': "'none'", - 'script-src-attr': "'none'", - 'script-src': "'none'", - 'script-src-elem': "'none'" + 'prefetch-src': ["'none'"], + 'script-src-attr': ["'none'"], + 'script-src': ["'none'", "'unsafe-eval'"], + 'script-src-elem': ["'none'"] } diff --git a/test/haketilo_test/unit/test_policy_enforcing.py b/test/haketilo_test/unit/test_policy_enforcing.py index 90a6ed9..4bc6470 100644 --- a/test/haketilo_test/unit/test_policy_enforcing.py +++ b/test/haketilo_test/unit/test_policy_enforcing.py @@ -31,12 +31,12 @@ nonce = 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855' allow_policy = {'allow': True} block_policy = { 'allow': False, - 'csp': f"prefetch-src 'none'; script-src-attr 'none'; script-src 'none'; script-src-elem 'none'; frame-src http://* https://*;" + 'csp': f"prefetch-src 'none'; script-src-attr 'none'; script-src 'none' 'unsafe-eval'; script-src-elem 'none'; frame-src http://* https://*;" } payload_policy = { 'mapping': 'somemapping', 'payload': {'identifier': 'someresource'}, - 'csp': f"prefetch-src 'none'; script-src-attr 'none'; script-src 'nonce-{nonce}'; script-src-elem 'nonce-{nonce}';" + 'csp': f"prefetch-src 'none'; script-src-attr 'none'; script-src 'nonce-{nonce}' 'unsafe-eval'; script-src-elem 'nonce-{nonce}';" } def content_script(): diff --git a/test/haketilo_test/unit/test_webrequest.py b/test/haketilo_test/unit/test_webrequest.py index 1244117..dc329b8 100644 --- a/test/haketilo_test/unit/test_webrequest.py +++ b/test/haketilo_test/unit/test_webrequest.py @@ -85,7 +85,7 @@ nonce = f'nonce-{sha256(nonce_source).digest().hex()}' payload_csp_header = { 'name': f'Content-Security-Policy', 'value': ("prefetch-src 'none'; script-src-attr 'none'; " - f"script-src '{nonce}'; script-src-elem '{nonce}';") + f"script-src '{nonce}' 'unsafe-eval'; script-src-elem '{nonce}';") } sample_payload_headers = [ @@ -107,7 +107,7 @@ sample_blocked_headers.append(sample_csp_header) sample_blocked_headers.append({ 'name': f'Content-Security-Policy', 'value': ("prefetch-src 'none'; script-src-attr 'none'; " - f"script-src 'none'; script-src-elem 'none';") + "script-src 'none' 'unsafe-eval'; script-src-elem 'none';") }) @pytest.mark.get_page('https://gotmyowndoma.in') diff --git a/test/haketilo_test/unit/utils.py b/test/haketilo_test/unit/utils.py index a49ce8c..9b3e4a0 100644 --- a/test/haketilo_test/unit/utils.py +++ b/test/haketilo_test/unit/utils.py @@ -228,12 +228,21 @@ def are_scripts_allowed(driver, nonce=None): return driver.execute_script( ''' document.haketilo_scripts_allowed = false; + document.haketilo_eval_allowed = false; const html_ns = "http://www.w3.org/1999/xhtml"; const script = document.createElementNS(html_ns, "script"); - script.innerHTML = "document.haketilo_scripts_allowed = true;"; + script.innerHTML = ` + document.haketilo_scripts_allowed = true; + eval('document.haketilo_eval_allowed = true;'); + `; if (arguments[0]) script.setAttribute("nonce", arguments[0]); (document.head || document.documentElement).append(script); + + if (document.haketilo_scripts_allowed != + document.haketilo_eval_allowed) + throw "scripts allowed but eval blocked"; + return document.haketilo_scripts_allowed; ''', nonce) |