From 1a807cfeb43f8e90bfde20c2f745e5339b1d3b0b Mon Sep 17 00:00:00 2001 From: Rene Luria Date: Wed, 8 Jul 2026 13:57:28 +0200 Subject: [PATCH] fix(security): add nonce-uniqueness test and fix caller indentation --- templates/index.html | 2 +- tests/test_main.py | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/templates/index.html b/templates/index.html index ac15cfa..3d3048b 100644 --- a/templates/index.html +++ b/templates/index.html @@ -600,7 +600,7 @@ localStorage.setItem('secret_phrase', data.secret_phrase); localStorage.setItem('secret_last_fetch', Date.now().toString()); - utils.showAlert(elements.secretResult, { title: 'Secret Phrase:', body: data.secret_phrase }, 'success'); + utils.showAlert(elements.secretResult, { title: 'Secret Phrase:', body: data.secret_phrase }, 'success'); } else { // Clear cached secret if user is no longer authorized localStorage.removeItem('secret_phrase'); diff --git a/tests/test_main.py b/tests/test_main.py index fedc6fa..41b2f04 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -51,6 +51,19 @@ def test_root_serves_csp_with_nonce(): nonce = match.group(1) assert f'nonce="{nonce}"' in body +def test_root_csp_nonce_is_unique_per_request(): + """Test that each GET / response gets a fresh CSP nonce (not module-level/static).""" + import re + n1 = re.search( + r"nonce-([A-Za-z0-9_-]+)", + client.get("/").headers.get("content-security-policy", ""), + ).group(1) + n2 = re.search( + r"nonce-([A-Za-z0-9_-]+)", + client.get("/").headers.get("content-security-policy", ""), + ).group(1) + assert n1 != n2 + @patch('main.verify_token') def test_validate_token_success(mock_verify_token): """Test successful token validation."""