From 44b946b8aeb2e08ff49d0530b8214c07a0cd6d59 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Mon, 20 Jul 2026 14:42:12 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[=EB=B3=B4?= =?UTF-8?q?=EC=95=88=20=EA=B0=9C=EC=84=A0]=20index.html=EC=9D=98=20CSP=20?= =?UTF-8?q?=EA=B0=95=EB=8F=84=20=EC=83=81=ED=96=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit index.html의 Content-Security-Policy(CSP)를 `default-src 'self'` 기반에서 엄격한 허용 목록(Allowlist) 방식인 `default-src 'none'`으로 강화했습니다. 필요한 리소스(script, style, img, font, connect)에 대해서만 `'self'`를 명시적으로 허용하고, 잠재적 공격 벡터를 줄이기 위해 `base-uri 'none'`과 `frame-src 'none'`을 설정했습니다. --- .jules/sentinel.md | 4 +++ index.html | 2 +- tests/test_index_security.py | 47 ++++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 tests/test_index_security.py diff --git a/.jules/sentinel.md b/.jules/sentinel.md index 4f173bc..4f1535d 100644 --- a/.jules/sentinel.md +++ b/.jules/sentinel.md @@ -38,3 +38,7 @@ **Vulnerability:** Missing input validation on `setLanguage()` could allow invalid strings (like Prototype Pollution payloads or arbitrary text) to be applied to the DOM (`lang` attribute) and stored in `localStorage`. **Learning:** The global `setLanguage` function assumed inputs would only come from predefined button clicks, skipping runtime validation. **Prevention:** Always sanitize and validate function arguments at the application boundary, even if the primary caller is trusted, to enforce defense in depth. +## 2026-07-20 - Enforce strict default-src 'none' CSP on index.html +**Vulnerability:** Weak CSP utilizing `default-src 'self'` could inadvertently allow loading unexpected resource types if they share the same origin, potentially widening the attack surface. +**Learning:** It is more secure to use an explicit allowlist approach (`default-src 'none'`) and explicitly grant `self` only to required resource types (script, style, img, font, connect). +**Prevention:** Always default to `default-src 'none'` and explicitly add directives for what is strictly needed, rather than relying on an implicitly broad `default-src 'self'`. diff --git a/index.html b/index.html index c40fea3..fd888db 100644 --- a/index.html +++ b/index.html @@ -3,7 +3,7 @@ - + 맥락지혜 연구실 | Contextual Wisdom Lab str: + """Return the index HTML source.""" + return INDEX.read_text(encoding="utf-8") + + +def _csp_content(html: str) -> str: + """Extract the CSP meta policy from the index HTML.""" + match = re.search( + r' None: + """The main site limits active content to strict whitelist.""" + policy = _csp_content(_index_html()) + + for directive in ( + "default-src 'none'", + "script-src 'self'", + "style-src 'self'", + "img-src 'self'", + "font-src 'self'", + "connect-src 'self'", + "object-src 'none'", + "base-uri 'none'", + "form-action 'none'", + "frame-src 'none'", + "upgrade-insecure-requests", + "require-trusted-types-for 'script'", + ): + assert directive in policy, f"Missing {directive} in CSP" + assert "'unsafe-inline'" not in policy + assert "'unsafe-eval'" not in policy