aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorWojtek Kosior <koszko@koszko.org>2022-06-01 18:14:09 +0200
committerWojtek Kosior <koszko@koszko.org>2022-06-10 14:13:57 +0200
commitf8dedf60638bffde3f92116db3f418d2e6260e80 (patch)
treeaa6da7b69f0db5c17c643505eaf9f2d8053d2daf /test
parent9bee4afaab8b89613e5e504829bdd4fae204e134 (diff)
downloadbrowser-extension-f8dedf60638bffde3f92116db3f418d2e6260e80.tar.gz
browser-extension-f8dedf60638bffde3f92116db3f418d2e6260e80.zip
allow eval() in injected scripts
Diffstat (limited to 'test')
-rw-r--r--test/haketilo_test/unit/test_policy_deciding.py61
-rw-r--r--test/haketilo_test/unit/test_policy_enforcing.py4
-rw-r--r--test/haketilo_test/unit/test_webrequest.py4
-rw-r--r--test/haketilo_test/unit/utils.py11
-rw-r--r--test/haketilo_test/world_wide_library.py19
5 files changed, 62 insertions, 37 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)
diff --git a/test/haketilo_test/world_wide_library.py b/test/haketilo_test/world_wide_library.py
index 2d227dd..92ce97e 100644
--- a/test/haketilo_test/world_wide_library.py
+++ b/test/haketilo_test/world_wide_library.py
@@ -152,7 +152,8 @@ sample_resource_templates.append({
'id_suffix': 'a-w-required-mapping-v1',
'files_count': 1,
'dependencies': [],
- 'required_mappings': [{'identifier': 'mapping-a'}]
+ 'required_mappings': [{'identifier': 'mapping-a'}],
+ 'include_in_query': False
})
sample_resource_templates.append({
@@ -160,7 +161,8 @@ sample_resource_templates.append({
'files_count': 1,
'dependencies': [],
'required_mappings': [{'identifier': 'mapping-a'}],
- 'schema_ver': '2'
+ 'schema_ver': '2',
+ 'include_in_query': False
})
sample_resources_catalog = {}
@@ -193,23 +195,20 @@ for srt in sample_resource_templates:
sufs = [srt["id_suffix"], *[l for l in srt["id_suffix"] if l.isalpha()]]
patterns = [f'https://example_{suf}.com/*' for suf in set(sufs)]
- payloads = {}
+ mapping['payloads'] = {}
for pat in patterns:
- payloads[pat] = {'identifier': resource['identifier']}
+ mapping['payloads'][pat] = {'identifier': resource['identifier']}
- queryable_url = pat.replace('*', 'something')
- if queryable_url not in sample_queries:
- sample_queries[queryable_url] = []
+ if not srt.get('include_in_query', True):
+ continue
- sample_queries[queryable_url].append({
+ sample_queries.setdefault(pat.replace('*', 'something'), []).append({
'identifier': mapping['identifier'],
'long_name': mapping['long_name'],
'version': mapping_versions[1]
})
- mapping['payloads'] = payloads
-
for item in resource, mapping:
if 'required_mappings' in srt:
item['required_mappings'] = srt['required_mappings']