內容安全政策 (CSP) 不破壞網站指南

Security2026-09-18TryQuickToolBox

您聽說過內容安全政策 (CSP) 對於保護網站免受跨站腳本 (XSS) 和資料注入攻擊至關重要。但當您嘗試加入時,網站卻壞了:圖片消失、腳本停止執行、樣式不見。感覺像是在安全性和功能性之間取捨。其實不必如此。

在本指南中,您將學習一種實用、逐步的方法來部署 CSP 而不破壞網站。我們將涵蓋核心指令、如何使用 nonce 和 hash,以及如何安全地測試。最後,您將擁有一個能增強安全性而不犧牲使用者體驗的 CSP。

什麼是 CSP,為何會破壞網站?

內容安全政策是一種瀏覽器安全標準,讓您限制頁面上可以載入哪些資源(腳本、樣式、圖片、字型等)。它透過 HTTP 標頭傳遞,例如 Content-Security-Policy: default-src 'self'。

CSP 會破壞網站,因為它會封鎖任何不符合您政策的資源。如果您有內聯腳本、來自 CDN 的外部腳本或內聯樣式,除非明確允許,否則它們都會被封鎖。預設行為是封鎖所有不允許的內容,這就是為什麼嚴格的政策可能很快破壞網站。

關鍵是從寬鬆的政策開始,並在監控違規情況的同時逐步收緊。

您需要了解的核心 CSP 指令

CSP 使用指令來控制不同的資源類型。以下是最常見的:

您可以在一個標頭中設定多個指令,以分號分隔。例如:

Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https://images.example.com

每個指令接受以空格分隔的來源列表。來源可以是關鍵字如 'self'、'unsafe-inline'、'unsafe-eval',或 URL,或 nonce/hash。

逐步指南:部署 CSP 而不破壞網站

遵循以下步驟安全地推出 CSP。

  1. 從僅報告政策開始。 使用 Content-Security-Policy-Report-Only 標頭,而非強制執行的標頭。這讓您看到什麼會被封鎖,而不實際封鎖。
  2. 設定寬鬆政策。 從類似 default-src 'self' 'unsafe-inline' 'unsafe-eval' https: 開始,允許大多數內容。這能最小化破壞。
  3. 收集違規報告。 設定 report-uri 指向記錄違規的端點。檢閱這些報告以識別被封鎖的資源。
  4. 修復違規。 更新您的程式碼以避免內聯腳本/樣式,或加入 nonce/hash。將外部資源移至允許的網域。
  5. 逐步收緊政策。 重構後移除 'unsafe-inline' 和 'unsafe-eval'。縮小允許的網域。
  6. 切換到強制執行模式。 一旦報告顯示沒有意外封鎖,將標頭改為 Content-Security-Policy(不含 -Report-Only)。
  7. 持續監控。 保持報告端點活躍以捕捉新問題。

這種漸進式方法確保您在提升安全性的同時不會破壞網站。

為內聯腳本使用 Nonce 和 Hash

內聯腳本是 CSP 破壞的常見原因。與其允許 'unsafe-inline',不如使用 nonce(一次性數字)或 hash。

Nonce 方法: 為每個請求生成隨機 nonce,加入您的 CSP 標頭,並包含在您的 script 標籤中。

Content-Security-Policy: script-src 'nonce-abc123'
<script nonce="abc123">...</script>

Hash 方法: 計算內聯腳本的 SHA hash 並加入政策。

Content-Security-Policy: script-src 'sha256-xyz...'

Hash 最適合不常變更的靜態內聯腳本。Nonce 則更適合動態內容。

對於樣式,您也可以使用 nonce 或 hash,但請注意,帶有 nonce 的 style-src 不涵蓋內聯樣式屬性(例如 style="...")。對於這些,您需要 'unsafe-inline' 或重構為類別。

常見 CSP 指令及其影響

指令 控制內容 常見來源
default-src 所有資源類型的後備 'self', https:
script-src JavaScript 來源 'self', 'nonce-...', 'sha256-...', https://cdn.com
style-src CSS 來源 'self', 'unsafe-inline', 'nonce-...'
img-src 圖片來源 'self', data:, https://images.com
connect-src AJAX、WebSocket、fetch 'self', https://api.com
font-src 網頁字型 'self', https://fonts.gstatic.com
frame-src Iframes 'self', https://youtube.com

在建立政策時,將此表作為快速參考。

測試和監控您的 CSP

在強制執行之前,徹底測試。使用瀏覽器開發者工具:Console 標籤會將 CSP 違規顯示為錯誤。Network 標籤顯示 CSP 標頭。

對於自動化測試,考慮使用 Google 的 CSP Evaluator(線上)或 csp_evaluator npm 套件等工具。這些有助於識別弱政策。

設定報告端點以在生產環境中收集違規。您可以使用 Report URI 等服務,或建立自己的端點記錄到檔案或資料庫。定期分析報告以捕捉新問題。

記住:CSP 不是萬靈丹。它是一層防禦。將其與輸入驗證、輸出編碼和其他安全最佳實踐結合使用。

常見問題

Content-Security-Policy 和 Content-Security-Policy-Report-Only 有什麼區別?

強制執行標頭 (Content-Security-Policy) 會封鎖違規。僅報告標頭 (Content-Security-Policy-Report-Only) 只報告違規而不封鎖,讓您安全地測試政策。

我可以將 CSP 與 onclick 等內聯事件處理程序一起使用嗎?

不行,內聯事件處理程序會被 CSP 封鎖,除非您使用 'unsafe-inline'(不建議)或重構為使用 addEventListener。為了更好的安全性,避免內聯事件處理程序。

如何使用 CSP 允許 Google Analytics?

將 Google Analytics 網域加入您的 script-src 和 connect-src 指令。例如:script-src 'self' https://www.googletagmanager.com; connect-src 'self' https://www.google-analytics.com。查看 Google 的文件以了解最新要求。

部署 CSP 不必是一個痛苦的過程。透過漸進式方法,您可以保護使用者免受 XSS 和其他攻擊,而不會中斷網站。從僅報告模式開始,修復違規,並隨著時間收緊政策。

如果您需要快速格式化或驗證 CSP 報告的 JSON 設定檔,試試我們的 JSON Formatter 來美化和除錯您的 JSON 資料。