進一步瞭解標頭,如何確保網站安全,並快速查詢最重要的詳細資料。
本文列出可用來保護網站的最重要的安全性標頭。您可以藉此瞭解網頁式安全性功能、瞭解如何在網站上實作這些功能,並在需要提醒時做為參考。
- 針對處理使用者資料的網站,建議採用安全性標頭:
- 內容安全政策 (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 類型,進而導致指令碼執行。
區隔其他網站與你的網站
網路的開放性能讓網站以可能違反應用程式安全性期望的方式彼此互動。這包括意外提出經過驗證的要求,或在攻擊者文件中嵌入其他應用程式的資料,藉此允許攻擊者修改或讀取應用程式資料。
會損害網路隔離狀態的常見安全漏洞包括 clickjacking、跨網站要求偽造 (CSRF)、跨網站指令碼納入作業 (XSSI) 和各種跨網站外洩事件。
- 使用 X-Frame-Options 可防止惡意網站嵌入文件。
- 使用跨來源資源政策 (CORP),防止跨來源網站納入您的網站資源。
- 使用跨來源開啟器政策 (COOP) 防止網站視窗遭到惡意網站互動。
- 使用跨源資源共享 (CORS) 控管跨來源文件存取自家網站資源的存取權。
如要進一步瞭解這些標頭,Post-Spectre Web Development 是非常實用的閱讀管道。
安全建立強大的網站
Spectre 會將任何載入到同一個瀏覽內容群組的資料,即使相同來源政策仍可供讀取。瀏覽器會限制可能利用特殊環境 (稱為「跨來源隔離」) 背後的安全漏洞。透過跨來源隔離,您可以使用 SharedArrayBuffer
等強大的功能。
- 使用跨來源嵌入程式政策 (COEP) 和 COOP,啟用跨來源隔離功能。
加密網站流量
如果應用程式沒有將傳輸中的資料全面加密,就可能出現加密問題,讓有心人士能瞭解使用者與應用程式的互動。
以下列舉幾種加密問題:未使用 HTTPS、複合型內容、沒有 Secure
屬性 (或 __Secure
前置字元) 設定的 Cookie,或是放寬 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 Evaluator 是適合評估 CSP 的好工具,但同時也是以 Nonce 為基礎的嚴格 CSP 範例。使用開發人員工具查看使用情況。
支援的瀏覽器
CSP 其他注意事項
frame-ancestors
指令可協助網站防範點閱綁架行為;如果允許不受信任的網站嵌入網站,就會面臨風險。如想採用較簡單的解決方案,您可以使用X-Frame-Options
進行封鎖,但frame-ancestors
提供進階設定,可讓您僅允許特定來源做為嵌入程式。- 您可能曾使用 CSP 來確保自家網站的所有資源都是透過 HTTPS 載入。不過,由於目前大多數瀏覽器會封鎖複合型內容,因此關聯性越來越低。
- 您也可以在僅限報表模式中設定 CSP。
- 如果您無法將 CSP 設為伺服器端的標頭,也可以將其設為中繼標記。請注意,中繼標記不支援僅限報表模式 (但這可能會改變)。
瞭解詳情
信任的類型
DOM 型 XSS 是一種攻擊,可將惡意資料傳入支援動態程式碼執行 (例如 eval()
或 .innerHTML
) 的接收器。
受信任的類型提供工具,可用於撰寫、安全性審查及維護應用程式的 DOM XSS。您可以透過 CSP 啟用這類 API,並預設將危險網頁 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'
目前
require-trusted-types-for
指令唯一接受的值是'script'
。當然,您可以將信任類型與其他 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>) 限制允許的「Trusted Types」政策名稱,但這並非必要條件。</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 會導致錯誤。
支援的瀏覽器
瞭解詳情
- 運用受信任的類型,防範 DOM 型跨網站指令碼安全漏洞
- CSP:Require-trusted-types-for - HTTP | MDN
- CSP:可信任類型 - HTTP | MDN
- Trusted Types demo (信任類型示範):開啟開發人員工具檢查器,以便瞭解情況
X-Content-Type-Options
如果從您的網域提供惡意 HTML 文件 (例如上傳至相片服務的圖片包含有效的 HTML 標記),某些瀏覽器會將該文件視為作用中文件,並允許該文件在應用程式環境中執行指令碼,進而產生跨網站指令碼錯誤。
X-Content-Type-Options: nosniff
會指示瀏覽器在指定回應的 Content-Type
標頭中設定的 MIME 類型正確無誤,藉此防止這種情況。這個標頭建議用於所有資源。
使用範例
X-Content-Type-Options: nosniff
建議用法
針對您伺服器提供的所有資源,以及正確的 Content-Type
標頭,建議您使用 X-Content-Type-Options: nosniff
。
與文件 HTML 一併傳送的標頭範例
X-Content-Type-Options: nosniff Content-Type: text/html; charset=utf-8
支援的瀏覽器
瞭解詳情
X 影格選項
如果惡意網站可將您的網站內嵌為 iframe,攻擊者可能會利用 clickjacking 叫用使用者預期的動作。此外,在某些情況下,Spectre 類型攻擊可以讓惡意網站瞭解嵌入文件的內容。
X-Frame-Options
表示瀏覽器是否應在 <frame>
、<iframe>
、<embed>
或 <object>
中轉譯網頁。建議您為所有文件傳送此標頭,指明這些標頭是否允許其他文件嵌入。
使用範例
X-Frame-Options: DENY
建議用法
所有不適合嵌入的文件都應使用 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
建議用法
建議您以下列三個標頭中的其中一個來提供「所有」資源。
透過這個示範,您可以嘗試以下設定如何影響 Cross-Origin-Embedder-Policy: require-corp
環境下的資源載入。變更「 Cross-Origin-Resource-Policy」Cross-Origin-Resource-Policy下拉式選單,然後按一下「Reload the iframe」Cross-Origin-Resource-Policy或「Reload the image」Cross-Origin-Resource-Policy按鈕可查看效果。
允許載入資源 cross-origin
建議將 cross-origin
等類 CDN 服務套用至資源 (因為這些資源通常是由跨來源頁面載入),除非這些資源已透過 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()
開啟的跨來源視窗,或在沒有 rel="noopener"
的情況下使用 target="_blank"
的連結。因此,文件的任何跨來源開啟工具都不會參照文件,也無法與其互動。
使用範例
Cross-Origin-Opener-Policy: same-origin-allow-popups
建議用法
您可以觀看這個示範,試試看以下設定如何影響與跨來源彈出式視窗的通訊。變更文件和彈出式視窗的「 Cross-Origin-Opener-Policy」Cross-Origin-Opener-Policy下拉式選單,按一下「Open apop」Cross-Origin-Opener-Policy按鈕,然後點選「Send a postMessage」Cross-Origin-Opener-Policy,查看訊息是否確實送出。
從跨來源視窗隔離文件
設定 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 前,建議您先瞭解要求類型之間的差異。視要求詳細資料而定,系統會將要求歸類為「簡易要求」或「預檢要求」。
簡易要求的條件:
- 方法為
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 採用 require-corp
的單一值。傳送這個標頭,即可指示瀏覽器封鎖未透過 CORS 或 CORP 選擇加入的資源。
您可以在這個示範網站上,嘗試以下設定如何影響載入資源。變更「 Cross-Origin-Embedder-Policy」Cross-Origin-Embedder-Policy下拉式選單、「 Cross-Origin-Resource-Policy」Cross-Origin-Embedder-Policy下拉式選單、「Report Only」Cross-Origin-Embedder-Policy核取方塊,以便瞭解這些元件對載入資源的影響。此外,您也可以開啟回報端點示範,查看遭封鎖的資源是否回報。
啟用跨來源隔離
傳送 Cross-Origin-Embedder-Policy: require-corp
和 Cross-Origin-Opener-Policy: same-origin
,啟用跨來源隔離功能。
Cross-Origin-Embedder-Policy: require-corp Cross-Origin-Opener-Policy: same-origin
回報與 COEP 不相容的資源
您可以透過 Reporting 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
建議用法
收到含有 HTTP 的要求時,所有從 HTTP 轉換到 HTTPS 的網站都應以 Strict-Transport-Security
標頭回應。
Strict-Transport-Security: max-age=31536000
支援的瀏覽器