2026 年現代 Web 應用中的跨站腳本攻擊(XSS)與 CSP 安全標頭實作

concept%20visualization%20for%202026%20%E5%B9%B4%E...
發表時間:2026 年 09 月 16 日 | 更新日期:2026 年 09 月 16 日 | 編輯:雅寶社區編輯團隊
2026 年現代 Web 應用中的跨站腳本攻擊(XSS)與 CSP 安全標頭實作|const s' 's' 's from 'node:cry - 雅寶社區 · 頂客論壇

im from 'node:cry' 's'`,

});

res;

d;` }}

/>

</>

add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

add_header X-Content-Type-Options "nosniff" always;

add_header Referrer-Policy "strict-origin-when-cross-origin" always;

add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;

always 參數非常重要,它確保即使是 4xx 或 5xx 回應也會帶上安全標頭。很多人只在 200 回應上設定,結果錯誤頁面成為防護缺口。

若使用 Cloudflare,可以透過 Transform Rules 動態改寫回應標頭,或是在 Workers 中實作更細緻的 nonce 注入邏輯。對於需要動態 nonce 又不想改動應用程式碼的團隊,用邊緣運算做 HTML 重寫是一個常見折衷方案:Worker 攔截回應,產生 nonce,把標頭中所有合法的 <script> 標籤補上 nonce 屬性,再送出。

3-4 四階段漸進式導入流程

第一階段:盤點。列出所有外部資源網域、所有行內腳本與行內樣式、所有使用 eval 或 new Function 的位置、所有動態產生的 HTML 片段。這份清單決定了你的政策能有多嚴格。

第二階段:Report-Only 觀察。使用 Content-Security-Policy-Report-Only 部署完整政策,只回報不阻擋。連續觀察至少一至兩週,涵蓋各種使用者流程與裝置。把回報中的違規逐一分類為「需要修正的程式碼」與「需要放行的合法來源」。

第三階段:收斂與修正。把行內腳本改為外部檔案或加上 nonce;把 eval 依賴替換掉;移除不必要的第三方來源;為第三方腳本加上 SRI。每修正一項,就縮小一次政策。

第四階段:強制執行與監控。切換為強制模式後,持續監控回報,並把 CSP 違規納入告警系統。建議每次部署新功能時,都先在 Report-Only 環境測過一次。

3-5 常見破版原因與排查清單

  • 字型或圖片被擋:檢查 font-src 與 img-src 是否包含 CDN 網域,注意 data: 與 blob: 需要明確列出。
  • 樣式全跑掉:多半是 style-src 未允許行內樣式。若使用 CSS-in-JS 函式庫,請確認它是否支援 nonce 注入。
  • API 請求失敗:檢查 connect-src,WebSocket 需要 wss: 協定前綴。
  • 第三方登入無法運作:檢查 frame-src 與 form-action,並確認 OAuth 流程是否需要開啟彈窗(window.open 不受 CSP 限制,但新視窗中的頁面有自己的政策)。
  • 開發模式正常、正式環境破版:通常是因為開發模式使用了 eval 或注入的除錯腳本。請在正式環境設定中明確移除 'unsafe-eval' 並確認建置產物不含相關程式碼。
  • nonce 不一致:檢查是否有 Service Worker 或 CDN 快取了 HTML,導致標頭中的 nonce 與標籤上的 nonce 不同。
  • 四、縱深防禦:CSP 之外你還需要做的事

    CSP 是一道強力的防線,但它不是唯一的一道。真正穩固的防禦需要多層機制互相補位,任何一層被突破時,其他層仍能發揮作用。

    4-1 依上下文的輸出編碼(Context-Aware Output Encoding)

    這是對抗 XSS 的根本手段。所謂「依上下文」,意思是根據資料最終被放置的位置,採用不同的編碼策略:

  • HTML 內文:將 &、<、>、"、' 轉為對應的 HTML 實體。
  • HTML 屬性:屬性值一律用引號包起來,並額外跳脫引號字元。切勿把未經驗證的資料放進 href、src,尤其要阻擋 javascript:、data:text/html、vbscript: 等協定。
  • JavaScript 字串:除了跳脫引號與反斜線,還要處理 <、>、&、以及 U+2028、U+2029。現代做法是優先使用 JSON.stringify 搭配 < 的轉義。
  • URL 參數:使用 encodeURIComponent,並對整個 URL 做白名單驗證。
  • CSS 值:只允許經過驗證的色彩、長度或列舉值,永遠不要把使用者輸入當成完整的 CSS 片段。
  • 對於必須接受富文本的場景(例如論壇文章、商品描述),請使用經過社群驗證的消毒函式庫(如 DOMPurify),並採用「允許清單」模式而非「黑名單」模式。

    4-2 完整的安全標頭組合

    CSP 應與以下標頭一起使用,形成完整的防護網:

  • Strict-Transport-Security:強制使用 HTTPS,建議 max-age=63072000; includeSubDomains; preload。注意 preload 是不可逆的,確認所有子網域都支援 HTTPS 後再啟用。
  • X-Content-Type-Options: nosniff:阻止瀏覽器進行 MIME 類型嗅探,避免上傳的檔案被當成腳本執行。
  • Referrer-Policy: strict-origin-when-cross-origin:避免在跨站請求中洩漏完整 URL,減少敏感資訊外流。
  • Permissions-Policy:關閉不需要的瀏覽器功能,如 camera=()、microphone=()、geolocation=()、payment=()。
  • Cross-Origin-Opener-Policy 與 Cross-Origin-Embedder-Policy:啟用跨來源隔離,防禦 Spectre 類型的側通道攻擊,並解鎖 SharedArrayBuffer 等高效能 API。
  • Cross-Origin-Resource-Policy:控制你的資源可被哪些來源嵌入。
  • Cookie 屬性:Session Cookie 務必設定 HttpOnly(阻擋 JavaScript 讀取)、Secure(只透過 HTTPS 傳輸)、SameSite=Lax 或 Strict(緩解 CSRF)。若需要跨站使用,可以考慮 __Host- 前綴。
  • 4-3 第三方腳本治理與子資源完整性

    第三方腳本是你最難控制的一環,但可以透過以下手段降低風險:

  • 盤點與最小化:定期審查每個第三方腳本的實際用途與載入成本。很多「歷史遺留」的追蹤腳本早就沒人在看報表了,卻還掛在頁面上。
  • 使用子資源完整性(SRI):對固定版本的第三方腳本加上 integrity 與 crossorigin 屬性,確保檔案未被篡改。缺點是第三方更新版本時需要同步更新雜湊值。對於經常變動的腳本,可以改用 CSP 的 hash 機制或內部代理。
  • 建立內部代理層:把第三方腳本先下載到自己的 CDN 再提供,這樣可以實施版本鎖定、內容審查與緊急下架。
  • 設定載入順序與時機:非關鍵腳本使用 defer 或 async 載入,或延後到使用者互動後才載入,縮小攻擊視窗。
  • 建立供應鏈事件應變流程:假設某天早上你收到通知,某個常用 CDN 被入侵。你有沒有能力在 30 分鐘內找出所有引用該資源的頁面並切換到備援?這個流程必須事先演練。
  • 五、2026 年 CSP 導入檢查清單

    以下清單可以直接拿來當作團隊的導入驗收標準:

    是否已完整盤點所有外部資源網域與行內腳本?

    是否已使用 Report-Only 模式觀察至少一至兩週?

    是否已為每個回應產生唯一且不可預測的 nonce?

    是否已確認含 nonce 的 HTML 不會被 CDN 或 Service Worker 快取?

    是否已啟用 strict-dynamic 並移除不再需要的來源白名單?

  • 是否已設定 object-src 'none'、base-uri 'none'、frame-ancestors 'none'?
  • 是否已移除 'unsafe-inline' 與 'unsafe-eval'?
  • 是否已評估導入 Trusted Types,並以 default 政策進行觀察?
  • 是否已設定 Reporting API 並將違規報告接入監控系統?

  • 是否已同步部署 HSTS、X-Content-Type-Options、Referrer-Policy、Permissions-Policy?
  • 是否已為所有第三方腳本加上 SRI 或改用內部代理?

    是否已在 CI/CD 流程中加入安全標頭的自動化檢測?

    是否已建立 CSP 變更的回滾機制與責任人?

    六、常見問答

    Q1:導入 CSP 會不會嚴重影響網站效能?

    不會。CSP 的檢查是瀏覽器端的輕量比對,對效能影響微乎其微。真正可能影響效能的是「改用外部腳本檔案」帶來的額外請求,但這可以透過 HTTP/2 或 HTTP/3 的多工、以及正確的快取策略來抵銷。

    Q2:如果我的網站大量依賴行內樣式,該怎麼辦?

    優先改用外部樣式表。若無法避免(例如需要動態計算的主題變數),可以為 <style> 標籤加上 nonce。對於框架自動注入的行內樣式,請確認框架是否有支援 nonce 的設定選項,或考慮在部署時抽出樣式。

    Q3:CSP 真的能完全防住 XSS 嗎?

    不能。CSP 是「緩解」而非「根治」。它能大幅提高攻擊門檻、阻擋大部分自動化掃描工具,但若應用本身存在伺服器端渲染的注入、CSP 政策配置錯誤、或允許了可被濫用的來源,攻擊者仍有機會繞過。因此 CSP 必須與輸出編碼、Trusted Types、Cookie 保護等措施搭配使用。

    Q4:Report-Only 模式要觀察多久?

    至少涵蓋一個完整的業務週期(例如一週),若能涵蓋月結、促銷活動等流量高峰更好。重點是讓各種使用者流程、裝置與瀏覽器版本都被涵蓋到。

    Q5:Trusted Types 在非 Chromium 瀏覽器上怎麼辦?

    不支援的瀏覽器會忽略 require-trusted-types-for,網站仍能正常運作,只是少了那一層保護。你仍應在程式碼中使用 policy 建立信任型別,因為這部分在所有瀏覽器上都能正常運作——差別只在於是被強制還是自願遵守。

    結語:安全不是一次性任務,而是一條持續收斂的曲線

    2026 年的 Web 安全環境比以往任何時候都複雜。前端框架不斷推陳出新,AI 讓程式碼產出的速度遠超過安全審查的速度,第三方腳本構成了難以完全掌握的供應鏈,而攻擊者的工具同樣在進化。在這樣的環境下,期待「寫出絕對不會有 XSS 的程式碼」是不現實的;更務實的目標是:建立多層防禦,確保任何單一環節的失誤都不會直接導致災難性後果。

    CSP 正是這個思路的具體實踐。它不要求你一次到位——你可以從 Report-Only 開始,逐步收斂政策;可以先從 object-src 'none' 和 base-uri 'none' 這兩條低風險指令入手;可以在有餘力時再導入 nonce 與 strict-dynamic;最後再挑戰 Trusted Types。每一步都能帶來實質的安全增益,而且每一步都是可逆、可觀察、可回滾的。

    最後想提醒的是:安全政策如果沒有人維護,就會慢慢腐化。今天嚴格的政策,可能因為某次緊急上線被加入了 'unsafe-inline',然後就再也沒有人移除。建議把 CSP 違規報告納入日常監控,把安全標頭的檢查納入程式碼審查清單,並在每次架構變更時重新評估政策的適用性。當安全變成開發流程的一部分,而不是事後補救的負擔時,它才真正有可能長期維持下去。

    願各位的網站,既跑得快,也守得住。

    ```

    🏠 返回首頁