fix(audit): durcir les validations de securite

This commit is contained in:
GGThed
2026-08-17 13:51:37 -04:00
parent 06508cc7d6
commit f84cb4e3b6
5 changed files with 149 additions and 19 deletions
+16 -1
View File
@@ -31,6 +31,14 @@ INLINE_HANDLER = re.compile(
re.I,
)
# An event attribute assembled inside a JavaScript string is absent from the
# template DOM, so the expression above cannot see it. Once assigned through
# innerHTML it is still an inline handler and the CSP still refuses to run it.
DYNAMIC_INLINE_HANDLER = re.compile(
r'''["']on(?:click|change|submit|input|load|keyup|keydown|mouseover|focus|blur)\s*=''',
re.I,
)
#: Remaining inline handlers, per template. Lower these as you migrate;
#: never raise one. Templates absent from this map must have none.
#: No template may carry an inline event handler. The migration is done;
@@ -52,7 +60,8 @@ def _templates():
def _count_handlers(path):
with open(path, encoding='utf-8') as handle:
return len(INLINE_HANDLER.findall(handle.read()))
content = handle.read()
return len(INLINE_HANDLER.findall(content)) + len(DYNAMIC_INLINE_HANDLER.findall(content))
class TestPolicyHeader:
@@ -102,6 +111,12 @@ class TestPolicyHeader:
class TestInlineHandlerRatchet:
def test_a_handler_built_inside_a_javascript_string_is_counted(self, tmp_path):
template = tmp_path / 'dynamic-handler.html'
template.write_text("html += '<button onclick=\"work()\">';", encoding='utf-8')
assert _count_handlers(template) == 1
@pytest.mark.parametrize('relative,full', list(_templates()))
def test_a_template_never_gains_an_inline_handler(self, relative, full):
allowed = HANDLER_BUDGET.get(relative, 0)