HERMES-GIELIE/tests/test_pwa_manifest_csp.py
Basit Mustafa b072a6887c
fix(csp): add explicit manifest-src 'self' directive (#961)
PR #920 added static/manifest.json and sw.js for PWA support. The CSP
in _security_headers() had no explicit manifest-src directive, so browsers
fell back to default-src 'self' and emitted a console warning on every page
load. The fallback is functionally correct but non-compliant with CSP Level 3
best practice of declaring each directive explicitly.

Adds manifest-src 'self' before base-uri. No origin set is changed.
Regression test added alongside existing CSP coverage in test_pwa_manifest_csp.py.

Co-authored with Claude Sonnet 4.6 / Anthropic.
2026-04-24 10:44:46 -07:00

43 lines
1.9 KiB
Python

"""Regression test: CSP must declare an explicit manifest-src directive.
PR #920 added static/manifest.json for PWA support. Without an explicit
manifest-src directive the browser falls back to default-src and emits
a noisy console warning. This test locks the explicit directive in place.
"""
import sys
from pathlib import Path
ROOT = Path(__file__).parent.parent
sys.path.insert(0, str(ROOT))
class TestManifestSrcCSP:
"""manifest-src must be explicitly declared in the Content-Security-Policy."""
def _csp(self) -> str:
text = (ROOT / "api" / "helpers.py").read_text(encoding="utf-8")
start = text.find("Content-Security-Policy")
assert start != -1, "Content-Security-Policy not found in helpers.py"
# Grab the full CSP string (up to the closing paren of send_header)
chunk = text[start:start + 600]
return chunk
def test_manifest_src_self_present(self):
"""CSP must contain an explicit manifest-src 'self' directive."""
assert "manifest-src 'self'" in self._csp(), (
"manifest-src 'self' missing from CSP — browsers will fall back to "
"default-src and emit console warnings when loading the PWA manifest"
)
def test_manifest_src_is_explicit_not_just_default(self):
"""manifest-src must not rely solely on default-src fallback."""
csp = self._csp()
# Ensure manifest-src appears as its own directive keyword
assert "manifest-src" in csp, "manifest-src directive absent from CSP"
def test_existing_directives_unchanged(self):
"""Existing CSP directives must still be present after the manifest-src addition."""
csp = self._csp()
for directive in ("default-src 'self'", "script-src", "style-src",
"font-src", "connect-src", "base-uri 'self'", "form-action 'self'"):
assert directive in csp, f"Expected CSP directive missing: {directive}"