Content-Security-Policy: script-src 指令
Baseline 廣泛可用 *
HTTP Content-Security-Policy (CSP) 的 script-src 指令指定了 JavaScript 的有效來源。這不僅包括直接載入到 <script> 元素中的 URL,還包括像內聯指令碼事件處理程式(onclick)和可以觸發指令碼執行的 XSLT 樣式表。
| CSP 版本 | 1 |
|---|---|
| 指令型別 | 獲取指令 |
default-src 回退 |
是的。如果此指令缺失,使用者代理將查詢 default-src 指令。 |
語法
Content-Security-Policy: script-src 'none';
Content-Security-Policy: script-src <source-expression-list>;
此指令可以具有以下值之一
'none'-
不允許載入此型別的任何資源。單引號是強制性的。
<source-expression-list>-
一個空格分隔的源表示式值列表。如果此型別的資源與任何給定的源表示式匹配,則可以載入。對於此指令,獲取指令語法中列出的任何源表示式值都適用。
示例
允許來自可信域的資源
給定此 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"
crossorigin="anonymous"></script>
integrity 屬性可以有多個值,每個值都提供使用不同演算法計算的檔案雜湊值。為了載入外部指令碼,CSP 要求屬性中的所有有效雜湊值也必須在 CSP script-src 宣告中。因此,下面的指令碼不會載入,因為第二個雜湊值不在上面的 CSP 頭部中。
<script
src="https://example.com/example-framework.js"
crossorigin="anonymous"></script>
此規則僅適用於有效雜湊值。瀏覽器不識別的雜湊值將被忽略,因此下面的指令碼應該載入
<script
src="https://example.com/example-framework.js"
crossorigin="anonymous"></script>
子資源完整性包含有關計算雜湊值和使用 integrity 屬性的更多資訊。
不安全的內聯指令碼
注意:禁止內聯樣式和內聯指令碼是 CSP 提供的最大安全優勢之一。如果您絕對必須使用它們,有幾種機制可以允許它們。雜湊值適用於內聯指令碼和樣式,但不適用於事件處理程式。有關更多資訊,請參閱不安全的雜湊值。
要允許內聯指令碼和樣式,可以指定 'unsafe-inline'、nonce-source 或與內聯塊匹配的 hash-source。以下內容安全策略將允許所有內聯 <script> 元素
Content-Security-Policy: script-src 'unsafe-inline';
以下 <script> 元素將被策略允許
<script>
const inline = 1;
// …
</script>
允許所有內聯指令碼被認為是安全風險,因此建議改用 nonce-source 或 hash-source。要使用 nonce-source 允許內聯指令碼和樣式,您需要生成一個隨機 nonce 值(使用加密安全的隨機令牌生成器)並將其包含在策略中。值得注意的是,此 nonce 值需要動態生成,因為它必須對每個 HTTP 請求都是唯一的
Content-Security-Policy: script-src 'nonce-2726c7f26c'
然後,您需要將相同的 nonce 包含在 <script> 元素中
<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 頭部並且 script-src 指令中未指定 'unsafe-eval',則以下方法將被阻止並且不會產生任何效果
eval()Function()-
將字串字面量傳遞給以下方法時:
setTimeout("alert(\"Hello World!\");", 500); -
window.execScript()非標準 (僅限 IE < 11)
不安全的 WebAssembly 執行
'wasm-unsafe-eval' 源表示式控制 WebAssembly 的執行。如果頁面具有 CSP 頭部並且 script-src 指令中未指定 'wasm-unsafe-eval',則 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">),您需要使用帶有 'inline-speculation-rules' 源、雜湊源或 nonce 源的 script-src 指令。例如
Content-Security-Policy: script-src 'inline-speculation-rules'
規範
| 規範 |
|---|
| 內容安全策略級別 3 # directive-script-src |
瀏覽器相容性
載入中…