進一步瞭解可確保網站安全的標頭,並快速查看最重要的詳細資料。
本文列出可用來保護網站的重要安全性標頭。您可以使用這份文件瞭解網頁安全性功能,並學習如何在網站上導入這些功能,也可以在需要提醒時參考這份文件。
- 建議用於處理敏感使用者資料的網站的安全性標頭:
- 內容安全政策 (CSP)
- 信任的類型
- 建議所有網站都設定以下安全性標頭:
- X-Content-Type-Options
- X-Frame-Options
- 跨來源資源政策 (CORP)
- 跨來源開啟者政策 (COOP)
- HTTP 嚴格傳輸安全性 (HSTS)
- 具備進階功能的網站安全性標頭:
- 跨來源資源共享 (CORS)
- 跨來源嵌入政策 (COEP)
在深入瞭解安全性標頭之前,請先瞭解網路上已知的威脅,以及為何要使用這些安全性標頭。
保護網站免於遭受注入漏洞的侵害
當應用程式處理的未受信任資料會影響其行為,並通常導致攻擊者控制的腳本執行時,就會產生注入安全漏洞。插入錯誤造成的最常見安全漏洞是跨網站指令碼攻擊 (XSS),其各種形式包括反射的 XSS、已儲存 XSS、DOM 型 XSS 和其他變化版本。
一般來說,XSS 安全漏洞可讓攻擊者完整存取應用程式處理的使用者資料,以及同一網路來源中代管的任何其他資訊。
傳統的防禦措施包括持續使用自動逸出 HTML 範本系統、避免使用危險的 JavaScript API,以及將上傳的檔案託管於個別網域,並清理使用者控制的 HTML,以正確處理使用者資料。
- 使用內容安全政策 (CSP) 控管應用程式可執行的指令碼,以降低注入風險。
- 使用可信任的類型,強制執行傳遞至危險 JavaScript API 的資料消毒作業。
- 使用 X-Content-Type-Options 可避免瀏覽器誤解網站資源的 MIME 類型,進而導致指令碼執行。
將網站與其他網站隔離
網路的開放性讓網站可以以違反應用程式安全性預期的方式互動。這包括在攻擊者的文件中,意外地提出已驗證的要求或嵌入其他應用程式的資料,讓攻擊者修改或讀取應用程式資料。
破壞網路隔離功能的常見安全漏洞包括點擊劫持、跨網站偽造要求 (CSRF)、跨網站指令碼置入 (XSSI),以及各種跨網站外洩。
- 使用 X-Frame-Options 可防止惡意網站嵌入您的文件。
- 使用跨來源資源政策 (CORP) 來避免您的網站資源被跨來源網站納入。
- 使用跨來源開啟器政策 (COOP),防止網站視窗遭到惡意網站互動。
- 使用跨來源資源共享 (CORS) 功能,控制跨來源文件對網站資源的存取權。
如果您對這些標頭感興趣,不妨閱讀後 Spectre 時代的網路開發作業。
安全地打造功能強大的網站
Spectre 會將任何載入的資料放入同一個瀏覽內容群組,即使同源政策也可能會讀取。瀏覽器會限制可能會在稱為「跨來源隔離」的特殊環境中,利用漏洞的功能。透過跨來源隔離功能,您可以使用 SharedArrayBuffer
等強大功能。
- 搭配使用跨來源嵌入政策 (COEP) 和 COOP,即可啟用跨來源隔離功能。
加密網站流量
如果應用程式未完全加密傳輸中的資料,就會出現加密問題,讓竊聽攻擊者得以瞭解使用者與應用程式的互動情形。
以下情況可能會導致加密不足:未使用 HTTPS、混合內容、設定 Cookie 時未使用 Secure
屬性 (或 __Secure
前置字),或是寬鬆的 CORS 驗證邏輯。
- 使用 HTTP 嚴格傳輸安全性 (HSTS),透過 HTTPS 持續提供內容。
內容安全政策 (CSP)
跨網站指令碼攻擊 (XSS) 是一種攻擊,會利用網站上的安全漏洞,讓惡意指令碼得以插入並執行。
Content-Security-Policy
提供的額外層可限制頁面可執行的指令碼,藉此緩解 XSS 攻擊。
建議您使用下列其中一種方法啟用嚴格 CSP:
- 如果您在伺服器上算繪 HTML 網頁,請使用以 Nonce 為基礎的嚴格 CSP。
- 如果 HTML 必須以靜態方式提供或快取,例如單頁應用程式,請使用以雜湊為基礎的嚴格 CSP。
使用範例:以 Nonce 為基礎的 CSP
Content-Security-Policy:
script-src 'nonce-{RANDOM1}' 'strict-dynamic' https: 'unsafe-inline';
object-src 'none';
base-uri 'none';
建議用途
1. 使用以 Nonce 為基礎的嚴格 CSP {: #nonce-based-csp}
如果您在伺服器上算繪 HTML 網頁,請使用以 Nonce 為基礎的嚴格 CSP。
為伺服器端的每項要求產生新的指令碼 Nonce 值,並設定下列標頭:
伺服器設定檔
Content-Security-Policy: script-src 'nonce-{RANDOM1}' 'strict-dynamic' https: 'unsafe-inline'; object-src 'none'; base-uri 'none';
在 HTML 中,如要載入指令碼,請將所有 <script>
標記的 nonce
屬性設為相同的 {RANDOM1}
字串。
index.html
<script nonce="{RANDOM1}" src="https://example.com/script1.js"></script> <script nonce="{RANDOM1}"> // Inline scripts can be used with the <code>nonce</code> attribute. </script>
Google 相簿是很好的 Nonce 型 CSP 範例。請使用開發人員工具查看廣告素材的使用方式。
2. 使用以雜湊為基礎的嚴格 CSP {: #hash-based-csp}
如果 HTML 必須採用靜態或快取的方式提供 (例如您要建構單頁應用程式),請使用雜湊型 CSP。
伺服器設定檔
Content-Security-Policy: script-src 'sha256-{HASH1}' 'sha256-{HASH2}' 'strict-dynamic' https: 'unsafe-inline'; object-src 'none'; base-uri 'none';
在 HTML 中,您必須內嵌指令碼才能套用雜湊式政策,因為多數瀏覽器都不支援對外部指令碼進行雜湊處理。
index.html
<script> ...// your script1, inlined </script> <script> ...// your script2, inlined </script>
如要載入外部指令碼,請參閱「選項 B:雜湊型 CSP 回應標頭」一節下方的「動態載入來源指令碼」。
CSP 評估工具是一項評估 CSP 的絕佳工具,同時也是以 Nonce 為基礎的嚴格 CSP 範例。使用開發人員工具查看使用方式。
支援的瀏覽器
其他 CSP 注意事項
frame-ancestors
指令可防止網站遭到點擊劫持,如果允許不受信任的網站嵌入網站,就會面臨風險。如果您偏好簡單的解決方案,可以使用X-Frame-Options
封鎖載入作業,但frame-ancestors
提供進階設定,只允許特定來源做為嵌入者。- 您可能已使用CSP 確保所有網站資源都透過 HTTPS 載入。這項做法已不太重要,因為目前大多數瀏覽器都會封鎖混合內容。
- 您也可以在僅報表模式中設定 CSP。
- 如果無法將 CSP 設為伺服器端標頭,也可以將其設為中繼標記。請注意,請勿在中繼標記使用僅限報表模式 (但這可能會改變)。
瞭解詳情
信任類型
DOM 為基礎的 XSS 攻擊是指將惡意資料傳遞至支援動態程式碼執行的接收器 (例如 eval()
或 .innerHTML
) 的攻擊。
信任類型提供各項工具,可用來撰寫、安全性審查及維護應用程式,而不必使用 DOM XSS。您可以透過 CSP 啟用這些功能,並限制危險的網路 API 只能接受特殊物件 (信任類型),藉此讓 JavaScript 程式碼在預設情況下保持安全。
如要建立這些物件,您可以定義安全性政策,確保在將資料寫入 DOM 之前,一律套用安全性規則 (例如轉義或清理)。因此,這些政策是程式碼中唯一可能引入 DOM XSS 的地方。
使用方式示例
Content-Security-Policy: require-trusted-types-for 'script'
// Feature detection
if (window.trustedTypes && trustedTypes.createPolicy) {
// Name and create a policy
const policy = trustedTypes.createPolicy('escapePolicy', {
createHTML: str => {
return str.replace(/\</g, '<').replace(/>/g, '>');
}
});
}
// Assignment of raw strings is blocked by Trusted Types.
el.innerHTML = 'some string'; // This throws an exception.
// Assignment of Trusted Types is accepted safely.
const escaped = policy.createHTML('<img src=x onerror=alert(1)>');
el.innerHTML = escaped; // '&lt;img src=x onerror=alert(1)&gt;'
建議用途
-
針對危險的 DOM 匯出點強制使用信任類型 CSP 和信任類型標頭:
Content-Security-Policy: require-trusted-types-for 'script'
目前
'script'
是require-trusted-types-for
指令唯一可接受的值。當然,您也可以將信任類型與其他 CSP 指令合併使用:
將上述的 nonce 型 CSP 與信任類型合併:
Content-Security-Policy:
script-src 'nonce-{RANDOM1}' 'strict-dynamic' https: 'unsafe-inline';
object-src 'none';
base-uri 'none';
require-trusted-types-for 'script';
<aside class="note"><b>附註:</b>您可以設定額外的 <code>trusted-types</code> 指示語 (例如 <code>trusted-types myPolicy</code>),藉此限制允許的「信任類型」政策名稱。不過,這並非必要。</aside>
-
定義政策
政策:
// Feature detection
if (window.trustedTypes && trustedTypes.createPolicy) {
// Name and create a policy
const policy = trustedTypes.createPolicy('escapePolicy', {
createHTML: str => {
return str.replace(/\/g, '>');
}
});
}
-
套用政策
將資料寫入 DOM 時請使用以下政策:
// Assignment of raw strings are blocked by Trusted Types.
el.innerHTML = 'some string'; // This throws an exception.</p>
<p>// Assignment of Trusted Types is accepted safely.
const escaped = policy.createHTML('<img src="x" onerror="alert(1)">');
el.innerHTML = escaped; // '<img src=x onerror=alert(1)>'
使用 require-trusted-types-for 'script'
時,必須使用信任的類型。使用任何危險的 DOM API 與字串時,都會導致錯誤。
支援的瀏覽器
瞭解詳情
X-Content-Type-Options
如果從您的網域提供惡意 HTML 文件 (例如,上傳至相片服務的圖片包含有效的 HTML 標記),部分瀏覽器會將該文件視為主動文件,並允許在應用程式環境內執行指令碼,進而造成跨網站指令碼攻擊錯誤。
X-Content-Type-Options: nosniff
會指示瀏覽器根據特定回應的 Content-Type
標頭中設定的 MIME 類型正確無誤,藉此防止這個標頭。建議您為所有資源使用這個標頭。
使用範例
X-Content-Type-Options: nosniff
如何使用 X-Content-Type-Options
建議用法
建議您從伺服器提供的所有資源,以及正確的 Content-Type
標頭使用 X-Content-Type-Options: nosniff
。
透過文件 HTML 傳送的標頭範例
X-Content-Type-Options: nosniff
Content-Type: text/html; charset=utf-8
支援的瀏覽器
瞭解詳情
X-Frame-Options
如果惡意網站可以將您的網站嵌入為 iframe,可能會讓攻擊者利用點擊劫持機制,藉此叫用使用者做出的意外動作。此外,在某些情況下,Spectre 類型攻擊會讓惡意網站有機會瞭解嵌入文件的內容。
X-Frame-Options
會指出瀏覽器是否可在 <frame>
、<iframe>
、<embed>
或 <object>
中顯示網頁。建議所有文件傳送這個標頭,指出這些文件是否允許其他文件嵌入。
使用範例
X-Frame-Options: DENY
如何使用 X-Frame-Options
建議用法
所有未設計用於內嵌的文件都應使用 X-Frame-Options
標頭。
您可以試試下列設定對這個示範的 iFrame 載入作業有何影響。變更 X-Frame-Options
下拉式選單,然後按一下「Reload the iframe」按鈕。
防止其他網站嵌入您的網站
禁止任何其他文件嵌入。
X-Frame-Options: DENY
防止任何跨來源網站嵌入您的網站
只允許同源文件嵌入。
X-Frame-Options: SAMEORIGIN
支援的瀏覽器
瞭解詳情
跨來源資源政策 (CORP)
攻擊者可以嵌入其他來源的資源 (例如您的網站),藉此利用網路上的跨網站外洩,瞭解這些資源的相關資訊。
Cross-Origin-Resource-Policy
會指出可載入的網站組合,藉此降低這類風險。標頭會採用以下三個值之一:same-origin
、same-site
和 cross-origin
。建議所有資源傳送這個標頭,指出是否允許其他網站載入。
使用範例
Cross-Origin-Resource-Policy: same-origin
如何使用 CORP
建議用法
建議您全部資源都搭配下列三個標頭放送。
您可以在此示範中,嘗試以下設定對 Cross-Origin-Embedder-Policy: require-corp
環境下的載入資源有何影響。變更「Cross-Origin-Resource-Policy」下拉式選單,然後按一下「Reload the iframe」或「Reload the image」按鈕,即可查看效果。
允許載入資源 cross-origin
建議與 CDN 類似的服務將 cross-origin
套用至資源 (因為這類服務通常是由跨來源頁面載入),除非已透過 CORS 提供類似的效果。
Cross-Origin-Resource-Policy: cross-origin
限制從 same-origin
載入的資源
same-origin
應套用至僅由同源網頁載入的資源。您應將此設定套用至包含使用者機密資訊的資源,或是只從相同來源呼叫的 API 回應。
請注意,含有此標頭的資源仍可直接載入,例如在新的瀏覽器視窗中前往網址。跨來源資源政策只會保護資源,避免遭到其他網站嵌入。
Cross-Origin-Resource-Policy: same-origin
限制從 same-site
載入的資源
建議將 same-site
套用至與上述類似資源,但是希望由網站上的其他子網域載入的資源。
Cross-Origin-Resource-Policy: same-site
支援的瀏覽器
瞭解詳情
跨來源開發者政策 (COOP)
攻擊者的網站可以利用網頁式跨網站洩漏,在彈出式視窗中開啟其他網站,以便瞭解該網站的相關資訊。在某些情況下,這也可能會讓攻擊者利用 Spectre 進行側通道攻擊。
Cross-Origin-Opener-Policy
標頭可讓文件與透過 window.open()
開啟的跨來源視窗或含有 target="_blank"
但沒有 rel="noopener"
的連結隔離。因此,任何跨來源開啟者都不會參照該文件,也無法與該文件互動。
使用範例
Cross-Origin-Opener-Policy: same-origin-allow-popups
如何使用 COOP
建議用法
您可以嘗試在這個示範中,測試下列設定對與跨來源彈出式視窗的通訊有何影響。變更文件和彈出式視窗的「Cross-Origin-Opener-Policy」下拉式選單,按一下「Open a popup」按鈕,然後點選「Send a postMessage」,查看訊息是否確實傳送。
隔離跨來源視窗中的文件
設定 same-origin
會將文件與跨來源文件視窗隔離。
Cross-Origin-Opener-Policy: same-origin
將文件從跨來源視窗隔離,但允許彈出式視窗
設定 same-origin-allow-popups
可讓文件保留對彈出式視窗的參照,除非這些文件已使用 same-origin
或 same-origin-allow-popups
設定 COOP。這表示 same-origin-allow-popups
仍可保護文件,避免在以彈出式視窗開啟時被參照,但允許它與自己的彈出式視窗通訊。
Cross-Origin-Opener-Policy: same-origin-allow-popups
允許跨來源視窗參照文件
unsafe-none
是預設值,但您可以明確指出這份文件可由跨來源視窗開啟,並保留相互存取權。
Cross-Origin-Opener-Policy: unsafe-none
報表模式與 COOP 不相容
當 COOP 阻止與 Reporting API 的跨視窗互動時,您可以收到報表。
Cross-Origin-Opener-Policy: same-origin; report-to="coop"
COOP 也支援僅回報模式,因此您可以接收回報,而不必實際封鎖跨來源文件之間的通訊。
Cross-Origin-Opener-Policy-Report-Only: same-origin; report-to="coop"
支援的瀏覽器
瞭解詳情
跨源資源共享 (CORS)
與本文其他項目不同,跨來源資源共享 (CORS) 不是標頭,而是一種瀏覽器機制,可要求並允許存取跨來源資源。
根據預設,瀏覽器會強制執行同源政策,防止網頁存取跨來源資源。舉例來說,載入跨來源圖片時,即使圖片會以視覺方式顯示在網頁上,但網頁上的 JavaScript 仍無法存取圖片資料。資源提供者可以選擇使用 CORS,藉此放寬限制,並允許其他網站讀取資源。
使用範例
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true
如何使用 CORS
在瞭解如何設定 CORS 之前,建議您先瞭解請求類型的差異。視要求詳細資料而定,系統會將要求歸類為簡單要求或預檢要求。
簡易要求的 條件:
- 方法為
GET
、HEAD
或 POST
。
- 自訂標頭僅包含
Accept
、Accept-Language
、Content-Language
和 Content-Type
。
Content-Type
是 application/x-www-form-urlencoded
、multipart/form-data
或 text/plain
。
其他項目都會歸類為預檢要求。詳情請參閱跨源資源共享 (CORS) - HTTP | MDN。
建議用法
簡易要求
當要求符合簡易要求條件時,瀏覽器會傳送跨來源要求,並附上 Origin
標頭,指出要求來源。
要求標頭範例
Get / HTTP/1.1
Origin: https://example.com
回應標頭範例
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: https://example.com
表示 https://example.com
可以存取回應內容。任何網站都能讀取的資源可將這個標頭設為 *
,在這種情況下,瀏覽器只會要求不含憑證的請求。
Access-Control-Allow-Credentials: true
表示允許包含憑證 (Cookie) 的要求載入資源。否則,即使要求來源出現在 Access-Control-Allow-Origin
標頭中,系統仍會拒絕經過驗證的要求。
您可以嘗試在這個示範中,測試簡單要求如何影響在 Cross-Origin-Embedder-Policy: require-corp
環境下載入資源。勾選「跨源資源共享」核取方塊,並按一下「重新載入映像檔」按鈕,即可查看效果。
預檢要求
預檢要求前面會有一個 OPTIONS
要求,用於檢查是否允許傳送後續要求。
要求標頭範例
OPTIONS / HTTP/1.1
Origin: https://example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-PINGOTHER, Content-Type
Access-Control-Request-Method: POST
允許使用 POST
方法發出下列要求。
Access-Control-Request-Headers: X-PINGOTHER, Content-Type
可讓要求者在後續要求中設定 X-PINGOTHER
和 Content-Type
HTTP 標頭。
回應標頭範例
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400
Access-Control-Allow-Methods: POST, GET, OPTIONS
表示可使用 POST
、GET
和 OPTIONS
方法發出後續要求。
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
表示後續的要求可以包含 X-PINGOTHER
和 Content-Type
標頭。
Access-Control-Max-Age: 86400
表示可以快取預檢要求的結果達 86400 秒。
支援的瀏覽器
瞭解詳情
跨來源嵌入程式政策 (COEP)
為降低以 Spectre 為基礎的攻擊竊取跨來源資源的能力,系統預設會停用 SharedArrayBuffer
或 performance.measureUserAgentSpecificMemory()
等功能。
Cross-Origin-Embedder-Policy: require-corp
會禁止文件和工作站載入跨來源資源,例如圖片、指令碼、樣式表、iframe 及其他資源,除非這些資源明確選擇透過 CORS 或 CORP 標頭載入。COEP 可與 Cross-Origin-Opener-Policy
搭配使用,讓文件選擇採用跨來源隔離。
如要為文件啟用跨來源隔離功能,請使用 Cross-Origin-Embedder-Policy: require-corp
。
使用範例
Cross-Origin-Embedder-Policy: require-corp
如何使用 COEP
使用範例
COEP 採用 require-corp
的單一值。傳送這個標頭後,您可以指示瀏覽器封鎖未透過 CORS 或 CORP 啟用的載入資源。
您可以在這個示範中,嘗試以下設定對載入資源的影響。變更「Cross-Origin-Embedder-Policy」下拉式選單、「Cross-Origin-Resource-Policy」下拉式選單、「Report Only」核取方塊等,瞭解這些選項對載入資源的影響。此外,請開啟報表端點示範,看看系統是否回報了遭到封鎖的資源。
啟用跨來源隔離功能
透過與 Cross-Origin-Opener-Policy: same-origin
一併傳送 Cross-Origin-Embedder-Policy: require-corp
,即可啟用跨來源隔離功能。
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
回報與 COEP 不相容的資源
您可以使用報表 API 接收 COEP 造成的封鎖資源報表。
Cross-Origin-Embedder-Policy: require-corp; report-to="coep"
COEP 也支援僅報表模式,因此您可以接收報表,而不會實際阻擋載入資源。
Cross-Origin-Embedder-Policy-Report-Only: require-corp; report-to="coep"
支援的瀏覽器
瞭解詳情
HTTP 嚴格傳輸安全性 (HSTS)
透過純 HTTP 連線進行的通訊不會加密,因此網路層級的竊聽者可以存取已轉移的資料。
Strict-Transport-Security
標頭會通知瀏覽器,絕不應使用 HTTP 載入網站,而應改用 HTTPS。設定完成後,瀏覽器會在標頭中定義的時間長度內,使用 HTTPS 而非 HTTP 存取網域,且不會重新導向。
使用範例
Strict-Transport-Security: max-age=31536000
如何使用 HSTS
建議用途
所有從 HTTP 改用 HTTPS 的網站,在收到 HTTP 要求時,都應以 Strict-Transport-Security
標頭回應。
Strict-Transport-Security: max-age=31536000
支援的瀏覽器
瞭解詳情
延伸閱讀