進一步瞭解可確保網站安全的標頭,並快速查看最重要的詳細資料。
本文列出可用於保護網站的重要安全標頭。您可以使用這份文件瞭解網頁安全性功能,並學習如何在網站上導入這些功能,也可以在需要提醒時參考這份文件。
- 建議用於處理敏感使用者資料的網站的安全性標頭:
- 內容安全政策 (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
建議用法
建議您為伺服器提供的所有資源一併使用 X-Content-Type-Options: nosniff
和正確的 Content-Type
標頭。
透過文件 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
環境下載入資源。按一下「Cross-Origin Resource Sharing」核取方塊,然後按一下「Reload the image」按鈕,查看效果。
預先篩選的要求
預檢要求會先傳送 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
會禁止文件和 worker 載入跨來源資源,例如圖片、指令碼、樣式表、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-Embedder-Policy: require-corp
和 Cross-Origin-Opener-Policy: same-origin
,即可啟用跨來源隔離。
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
支援的瀏覽器
瞭解詳情
延伸閱讀