D-20260812-04|CSP 逐頁雜湊與不安全請求升級¶
背景與驅動力¶
Angular prerender 會在不同路由產生不同 inline import map、JSON-LD 與非阻塞 stylesheet handler;
單一靜態 CSP 無法在不放寬 unsafe-inline 的前提下涵蓋所有頁面。現行 generator 已採逐頁 hash,
但 canon 仍描述靜態常數,且 generator 漏掉原決策列入的 upgrade-insecure-requests。
考慮過的選項¶
- 全頁共用
script-src 'unsafe-inline':簡單但失去 inline script 注入防線,棄。 - 移除
upgrade-insecure-requests以支援 localhost:Chromium 實測 localhost 本就保留 HTTP,前提 不成立,且會讓正式站失去未來誤植 HTTP resource 時的縱深防禦,棄。 - 逐頁精確 SHA-256,加上固定安全 baseline 與
upgrade-insecure-requests(採納)。
決定¶
- production prerender 後遍歷每份 HTML,逐頁計算所有無
srcinline script 的 SHA-256;script-src固定含'self'與'wasm-unsafe-eval',永不加入'unsafe-inline'。 - 只有頁面含 inline event handler 時,才加入
'unsafe-hashes'與各 handler 的 SHA-256。 - 固定 baseline 含
upgrade-insecure-requests;localhost 煙測保留,且不以移除 production 安全 directive 作為本機開發相容手段。 connect-src 'self' wss: https:與 meta CSP 無frame-ancestors的既有決策不變。
後果與影響¶
每份 prerender HTML 只允許自身實際內嵌內容,新增或變更 inline 內容會自然得到新 hash,而不是 要求人工同步全站常數。正式站同時恢復 insecure subresource 升級保護。代價是 CSP 只能在 build 產物生成後確定,注入器與其測試因此成為 production build 的必要安全閘。
本決策修訂 D-20260703-01 的「靜態 CSP_META」實作描述;
build 時 meta 交付、scheme 級 connect-src 與 clickjacking 風險接受仍然有效。