CSP:script-src
HTTP Content-Security-Policy (CSP) script-src 指令指定 JavaScript 的有效來源。這不僅包括直接載入到 <script> 元素中的 URL,還包括內聯指令碼事件處理程式 (onclick) 和 XSLT 樣式表,這些樣式表可以觸發指令碼執行。
| CSP 版本 | 1 |
|---|---|
| 指令型別 | 獲取指令 |
default-src 回退 |
是。如果此指令不存在,使用者代理將查詢 default-src 指令。 |
語法
可以為 script-src 策略允許一個或多個來源
Content-Security-Policy: script-src <source>;
Content-Security-Policy: script-src <source> <source>;
來源
示例
允許來自可信域的資源
鑑於此 CSP 標頭僅允許來自 https://example.com 的指令碼
Content-Security-Policy: script-src https://example.com/
以下指令碼將被阻止,不會載入或執行
<script src="https://not-example.com/js/library.js"></script>
請注意,內聯事件處理程式也會被阻止
<button id="btn" onclick="doSomething()"></button>
您應該將它們替換為 addEventListener 呼叫
document.getElementById("btn").addEventListener("click", doSomething);
如果您無法替換內聯事件處理程式,可以使用 'unsafe-hashes' 源表示式來允許它們。有關更多資訊,請參閱 不安全雜湊。
使用雜湊允許外部指令碼
如上節所示,允許可信域是指定可以安全載入程式碼位置的寬泛方法。這是一種務實的做法,尤其是在您的網站使用許多資源並且您相信可信網站不會被入侵的情況下。
另一種方法是使用檔案雜湊來指定允許的指令碼。使用這種方法,<script> 元素中的外部檔案只能在它的 integrity 屬性中所有有效的雜湊值與 CSP 標頭中允許的值匹配時載入和執行。 子資源完整性 功能還會額外檢查下載的檔案是否具有指示的雜湊值,因此沒有被修改。這比信任域更安全,因為即使從受損網站載入,檔案也只會使用未修改的檔案。但是,它更細粒度,並且要求在更改關聯指令碼時在 CSP 和指令碼元素中更新雜湊值。
下面的 CSP 標頭演示了這種方法。它允許 SHA384 雜湊為 oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC 或 SHA256 雜湊為 fictional_value 的指令碼。
Content-Security-Policy: script-src 'sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC' 'sha256-fictional_value'
下面的 example-framework.js 指令碼應該載入,因為其 integrity 屬性中的雜湊值也存在於 CSP 中(前提是檔案在下載後實際上確實具有該雜湊值!)。
<script
src="https://example.com/example-framework.js"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
crossorigin="anonymous"></script>
integrity 屬性可以具有多個值,每個值都提供使用不同演算法計算的檔案的雜湊值。為了載入外部指令碼,CSP 要求屬性中所有有效的雜湊值也必須在 CSP script-src 宣告中。因此,下面的指令碼將不會載入,因為第二個雜湊值不存在於上面的 CSP 標頭中。
<script
src="https://example.com/example-framework.js"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC sha256-not-in-csp"
crossorigin="anonymous"></script>
此規則僅適用於有效的雜湊值。瀏覽器無法識別為雜湊值的將被忽略,因此以下指令碼應載入
<script
src="https://example.com/example-framework.js"
integrity="invalid-or-unsupported-hash sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
crossorigin="anonymous"></script>
子資源完整性 包含有關計算雜湊值和使用 integrity 屬性的更多資訊。
不安全的內聯指令碼
注意:禁止內聯樣式和內聯指令碼是 CSP 提供的最大安全優勢之一。如果您絕對必須使用它們,有一些機制將允許它們。雜湊適用於內聯指令碼和樣式,但不適用於事件處理程式。有關更多資訊,請參閱 不安全雜湊。
要允許內聯指令碼和樣式,可以指定 'unsafe-inline'、nonce-source 或與內聯塊匹配的雜湊-source。以下內容安全策略將允許所有內聯 <script> 元素
Content-Security-Policy: script-src 'unsafe-inline';
以下 <script> 元素將被策略允許
<script>
const inline = 1;
// …
</script>
允許所有內聯指令碼被認為是一種安全風險,因此建議使用 nonce-source 或雜湊-source。要使用 nonce-source 允許內聯指令碼和樣式,您需要生成一個隨機的 nonce 值(使用密碼學安全的隨機令牌生成器)並將其包含在策略中。重要的是要注意,此 nonce 值需要動態生成,因為它必須對每個 HTTP 請求唯一
Content-Security-Policy: script-src 'nonce-2726c7f26c'
然後,您需要在 <script> 元素中包含相同的 nonce
<script nonce="2726c7f26c">
const inline = 1;
// …
</script>
或者,您可以從內聯指令碼建立雜湊值。CSP 支援 sha256、sha384 和 sha512。
Content-Security-Policy: script-src 'sha256-B2yPHKaXnvFWtRChIbabYmUBFZdVfKKXHbWtWidDVF8='
生成雜湊值時,不要包含 <script> 標籤,並注意大小寫和空格很重要,包括前導或尾隨空格。
<script>
const inline = 1;
</script>
不安全的雜湊值
針對具有雜湊值的內聯資源的策略(如 script-src 'sha256-{HASHED_INLINE_SCRIPT}')允許指令碼和樣式透過其雜湊值,但不允許事件處理程式
<!-- Allowed by CSP: script-src 'sha256-{HASHED_INLINE_SCRIPT}' -->
<script>
const inline = 1;
</script>
<!-- CSP: script-src 'sha256-{HASHED_EVENT_HANDLER}'
will not allow this event handler -->
<button onclick="myScript()">Submit</button>
如果您無法將程式碼更新為等效的 addEventListener 呼叫,則可以改為使用 'unsafe-hashes' 源表示式,而不是允許 'unsafe-inline'。鑑於一個 HTML 頁面包含以下內聯事件處理程式
<!-- I want to use addEventListener, but I can't :( -->
<button onclick="myScript()">Submit</button>
以下 CSP 標頭將允許指令碼執行
Content-Security-Policy: script-src 'unsafe-hashes' 'sha256-{HASHED_EVENT_HANDLER}'
不安全的 eval 表示式
'unsafe-eval' 源表示式控制幾種從字串建立程式碼的指令碼執行方法。如果頁面具有 CSP 標頭並且 'unsafe-eval' 未在 script-src 指令中指定,則以下方法將被阻止,並且不會有任何效果
eval()Function()- 將字串文字傳遞給類似的方法時:
setTimeout("alert(\"Hello World!\");", 500); window.execScript()非標準 (僅 IE < 11)
不安全的 WebAssembly 執行
'wasm-unsafe-eval' 源表示式控制 WebAssembly 執行。如果頁面具有 CSP 標頭並且 'wasm-unsafe-eval' 未在 script-src 指令中指定,則 WebAssembly 將被阻止在頁面上載入和執行。
'wasm-unsafe-eval' 源表示式比 'unsafe-eval' 更具體,後者允許 WebAssembly 的編譯(和例項化),例如,允許在 JavaScript 中使用 eval 操作。如果使用 'unsafe-eval' 源關鍵字,則會覆蓋 CSP 策略中 'wasm-unsafe-eval' 的任何出現。
Content-Security-Policy: script-src 'wasm-unsafe-eval'
strict-dynamic
'strict-dynamic' 源表示式指定將明確授予標記中存在指令碼的信任(透過使用 nonce 或雜湊對其進行補充)應傳播到該根指令碼載入的所有指令碼。同時,任何允許列表或源表示式(如 'self' 或 'unsafe-inline')將被忽略。
例如,類似 script-src 'strict-dynamic' 'nonce-R4nd0m' https://allowlisted.example.com/ 的策略將允許載入具有 <script nonce="R4nd0m" src="https://example.com/loader.js"> 的根指令碼,並將該信任傳播到 loader.js 載入的任何指令碼,但禁止載入來自 https://allowlisted.example.com/ 的指令碼,除非它們帶有 nonce 或從可信指令碼載入。
Content-Security-Policy: script-src 'strict-dynamic' 'nonce-someNonce'
或者
Content-Security-Policy: script-src 'strict-dynamic' 'sha256-base64EncodedHash'
可以以向後相容的方式部署 strict-dynamic,而無需使用者代理嗅探。策略
Content-Security-Policy: script-src 'unsafe-inline' https: 'nonce-abcdefg' 'strict-dynamic'
在支援 CSP1 的瀏覽器中將表現得像 'unsafe-inline' https:,在支援 CSP2 的瀏覽器中將表現得像 https: 'nonce-abcdefg',在支援 CSP3 的瀏覽器中將表現得像 'nonce-abcdefg' 'strict-dynamic'。
允許推測規則
要在指令碼中包含 推測規則(另請參閱 <script type="speculationrules">),您需要使用 script-src 指令以及 'inline-speculation-rules' 源和雜湊-source 或 nonce-source。例如
Content-Security-Policy: script-src 'inline-speculation-rules' 'sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC'
規範
| 規範 |
|---|
| 內容安全策略級別 3 # directive-script-src |
瀏覽器相容性
BCD 表僅在瀏覽器中載入