內容安全政策 (CSP) 有助於確保網頁上載入的所有內容皆獲得網站擁有者的信任。CSP 可防範跨網站指令碼攻擊 (XSS) 攻擊,因為這類攻擊能封鎖攻擊者插入的不安全指令碼。不過,如果 CSP 不夠嚴格,就可以輕易略過。詳情請參閱採用嚴格的內容安全政策 (CSP) 來減輕跨網站指令碼攻擊 (XSS)。Lighthouse 會收集主要文件上強制執行的 CSP,並在 CSP Evaluator 回報相關問題 (如果可以略過)。

無法略過 CSP 的必要做法
導入下列做法,確保無法略過 CSP。如果系統可以略過 CSP,Lighthouse 會發出高嚴重性的警告。
CSP 指定 XSS
如要指定 XSS,請讓 CSP 加入 script-src
、object-src
和 base-uri
指令。CSP 也不應出現語法錯誤。
script-src
和 object-src
可分別保護網頁不受不安全的指令碼和不安全的外掛程式侵擾。或者,default-src
可用於設定廣泛的政策,取代許多指令,包括 script-src
和 object-src
。
base-uri
可防止未經授權的 <base>
標記插入,這些標記可用來將所有相對網址 (例如指令碼) 重新導向至攻擊者控制的網域。
CSP 會使用 Nonce 或雜湊,避免許可清單略過許可清單
為 script-src
設定許可清單的 CSP 會假設,來自信任網域的所有回應都安全無虞,且能以指令碼的形式執行。不過,這個假設不適用於現代應用程式。一些常見的良性模式 (例如公開 JSONP 介面和 AngularJS 程式庫副本) 可讓攻擊者逃離 CSP 的信任範圍。
在實務上,應用程式作者可能看不見,但出現 XSS 錯誤的攻擊者,可以規避大部分的 script-src
許可清單,而且對於插入指令碼的攻擊來說,幾乎沒有足夠防護。相反地,以 Nonce 為基礎和雜湊為基礎的方法則不受這些問題影響,而且能讓您更輕鬆地採用及維護更安全的政策。
例如,此程式碼使用在受信任網域上託管的 JSONP 端點,插入攻擊者控制的指令碼:
CSP:
script-src https://trusted.example.com
HTML:
<script src="https://trusted.example.com/path/jsonp?callback=alert(document.domain)//"></script>
為避免遭到忽略,CSP 應允許個別使用 Nonce 或雜湊指令碼,並使用「strict-dynamic」而非許可清單
有關安全 CSP 的其他建議
實作下列做法來提升安全性與相容性。如果 CSP 未遵循其中一項建議,Lighthouse 會發出中嚴重性警示。
設定 CSP 報告
設定報告目的地有助於監控任何故障情形。您可以使用 report-uri
或 report-to
指令設定回報目的地。部分新式瀏覽器目前不支援 report-to
,因此建議您同時使用或只使用 report-uri
。
如果任何內容違反 CSP,瀏覽器就會傳送報告至設定的目的地。請確定您已在這個目的地中設定可以處理這些報表的應用程式。
在 HTTP 標頭中定義 CSP
您可在中繼標記中定義 CSP,如下所示:
<meta http-equiv="Content-Security-Policy" content="script-src 'none'">
不過,請盡可能在 HTTP 回應標頭中定義 CSP。中繼標記之前的插入會略過 CSP。此外,中繼標記 CSP 不支援 frame-ancestors
、sandbox
和報告。
確保 CSP 與先前版本相容
並非所有瀏覽器都支援 CSP Nonce/Hash,因此建議將 unsafe-inline
新增為不符合規定的瀏覽器備用方案。如果瀏覽器支援 Nonce/Hash,系統會忽略 unsafe-inline
。
同樣地,也不是所有瀏覽器都支援 strict-dynamic
。建議您為所有不符規定的瀏覽器設定許可清單,做為備用選項。支援 strict-dynamic
的瀏覽器會略過許可清單。
如何開發嚴格 CSP
以下示例說明如何使用嚴格 CSP 搭配 Nonce 政策。
CSP:
script-src 'nonce-random123' 'strict-dynamic' 'unsafe-inline' https:;
object-src 'none';
base-uri 'none';
report-uri https://reporting.example.com;
HTML:
<script nonce="random123" src="https://trusted.example.com/trusted_script.js"></script>
每次載入頁面時,random123
都會是伺服器端產生的任何 Base64 字串。由於 Nonce 和 strict-dynamic
,新版瀏覽器會忽略 unsafe-inline
和 https:
。如要進一步瞭解如何採用嚴格 CSP,請參閱 Strict CSP 指南。
您可以使用 Lighthouse 和 CSP Evaluator 檢查 CSP 是否可能略過。如果想測試新的 CSP,但不想中斷現有網頁的風險,請使用 Content-Security-Policy-Report-Only
做為標頭名稱,在報表專用模式中定義 CSP。這項操作會將違反 CSP 規定的內容傳送至您使用 report-to
和 report-uri
設定的所有報表目的地,但不會實際強制執行 CSP。