test_landing_security.py
python
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1
docs: MuseHub-first before ISR #74 — staging solidify NEXT
Human
9 hours ago
| 1 | """Security tests — landing HTML must not leak secrets or load external scripts.""" |
| 2 | |
| 3 | from __future__ import annotations |
| 4 | |
| 5 | import re |
| 6 | from pathlib import Path |
| 7 | |
| 8 | from tools.landing.validate import SECRET_PATTERNS, validate_landing |
| 9 | |
| 10 | KIT_ROOT = Path(__file__).resolve().parents[2] |
| 11 | LANDING_DIR = KIT_ROOT / "docs" / "landing" |
| 12 | |
| 13 | |
| 14 | def test_no_external_script_tags() -> None: |
| 15 | for html_path in LANDING_DIR.rglob("*.html"): |
| 16 | text = html_path.read_text(encoding="utf-8") |
| 17 | assert not re.search(r"""<script[^>]+src\s*=\s*["']https?://""", text, re.I) |
| 18 | assert "eval(" not in text.lower() |
| 19 | theme = LANDING_DIR / "assets" / "theme.js" |
| 20 | assert theme.is_file() |
| 21 | assert "eval(" not in theme.read_text(encoding="utf-8").lower() |
| 22 | |
| 23 | |
| 24 | def test_no_secret_patterns_in_landing_html() -> None: |
| 25 | for html_path in LANDING_DIR.rglob("*.html"): |
| 26 | text = html_path.read_text(encoding="utf-8") |
| 27 | for pattern in SECRET_PATTERNS: |
| 28 | assert not pattern.search(text), f"{html_path.name} matched {pattern.pattern}" |
| 29 | |
| 30 | |
| 31 | def test_validate_rejects_injected_secret(tmp_path: Path) -> None: |
| 32 | landing = tmp_path / "docs" / "landing" |
| 33 | landing.mkdir(parents=True) |
| 34 | (landing / "manifest.yaml").write_text( |
| 35 | (KIT_ROOT / "docs" / "landing" / "manifest.yaml").read_text(encoding="utf-8") |
| 36 | ) |
| 37 | bad_html = (KIT_ROOT / "docs" / "landing" / "index.html").read_text(encoding="utf-8") |
| 38 | bad_html = bad_html.replace( |
| 39 | "</head>", |
| 40 | '<meta name="api_key" content="sk-abcdefghijklmnopqrstuvwxyz1234567890"></head>', |
| 41 | ) |
| 42 | (landing / "index.html").write_text(bad_html, encoding="utf-8") |
| 43 | scenarios = landing / "scenarios" |
| 44 | scenarios.mkdir() |
| 45 | (scenarios / "index.html").write_text( |
| 46 | (KIT_ROOT / "docs" / "landing" / "scenarios" / "index.html").read_text(encoding="utf-8") |
| 47 | ) |
| 48 | (landing / "assets").mkdir() |
| 49 | (landing / "assets" / "style.css").write_text("body{}", encoding="utf-8") |
| 50 | (tmp_path / "LICENSE").write_text( |
| 51 | "MIT License\nCopyright 2026 Overseer Kit contributors\n", |
| 52 | encoding="utf-8", |
| 53 | ) |
| 54 | (tmp_path / "SECURITY.md").write_text("Reporting a vulnerability\n", encoding="utf-8") |
| 55 | |
| 56 | result = validate_landing(tmp_path) |
| 57 | assert not result.ok |
| 58 | assert any(e.startswith("secret_leak:") for e in result.errors) |
File History
2 commits
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1
docs: MuseHub-first before ISR #74 — staging solidify NEXT
Human
9 hours ago
sha256:4671b7f787ddbe63ced31c895b688c77ab495653b65a730b423329f26b3c1439
feat: K1-P1 complete — agent provenance, build-verification…
Sonnet 4.6
patch
52 days ago