HTTP安全標頭:HSTS、CSP等設定說明
說明HSTS、CSP、X-Frame-Options、Referrer-Policy與Permissions-Policy的作用與建議值,以及標示為「需檢查」的標頭為何不一定是弱點。
什麼是安全標頭
每個HTTP回應都以標頭開頭,也就是Content-Type: text/html這類名稱與值的組合。其中有幾個會改變瀏覽器處理頁面的方式。傳送這些標頭不需成本,會套用到每位訪客,而且是在伺服器、代管平台或內容傳遞網路(CDN)上設定,而不是寫在頁面的HTML中。
IPNixa在_headers檔案中設定自己的標頭,由Cloudflare隨每個頁面一併提供。本站的檢查工具會從我們的伺服器請求你輸入的網址,最多跟隨三次重新導向,並讀取最終回應的標頭。
最重要的六個標頭
以下是檢查工具會評定的標頭。表中的值是常見且安全的起點,請依網站需求調整。
| 標頭 | 防範的問題 | 常見值 |
|---|---|---|
| Strict-Transport-Security (HSTS) | 首次造訪後,連線被降級為一般HTTP | max-age=31536000; includeSubDomains |
| Content-Security-Policy (CSP) | 被注入的指令碼得以執行;可藉此限制跨網站指令碼攻擊 | default-src 'self'; script-src 'self'; frame-ancestors 'none' |
| X-Frame-Options或CSP frame-ancestors | 其他網站在隱藏框架中載入頁面(點擊劫持) | DENY,或frame-ancestors 'none' |
| X-Content-Type-Options | 瀏覽器自行猜測檔案類型,並把資料當作指令碼執行 | nosniff |
| Referrer-Policy | 包含路徑與查詢字串的完整頁面網址洩漏給其他網站 | strict-origin-when-cross-origin |
| Permissions-Policy | 頁面或其嵌入的框架使用攝影機、麥克風或位置資訊 | camera=(), microphone=(), geolocation=() |
IPNixa檢查工具如何評定各標頭
每個標頭會得到三種狀態之一:存在、需檢查或未提供。「需檢查」表示標頭存在,但其值不符合下列規則;這是提醒你仔細查看,而不是安全分數。
- HSTS只出現一次且max-age至少為15552000秒(180天)時,判定為「存在」。max-age較短或為零則標示為「需檢查」。
- CSP透過script-src或default-src控制指令碼,且整個政策中沒有'unsafe-inline'、'unsafe-eval'或單獨的*時,判定為「存在」。僅回報(report-only)政策不會封鎖任何內容,因此列為「未提供」。
- 框架控制:frame-ancestors指令限定為'none'、'self'或確切位址,或X-Frame-Options設為DENY或SAMEORIGIN時,判定為「存在」。
- X-Content-Type-Options只有值為nosniff時,才判定為「存在」。
- Referrer-Policy的最後一個值為no-referrer、same-origin、strict-origin或strict-origin-when-cross-origin時,判定為「存在」。瀏覽器會採用它能理解的最後一個值,因此清單以最後一項判斷。
- Permissions-Policy只要有傳送就判定為「存在」,因為合適的功能清單取決於網站本身。
實際網站傳送哪些標頭:範例
我們在2026年11月2日,以檢查工具所用的同一個使用者代理程式請求五個網站的首頁,並以IPNixa的評定規則分析回應。標頭經常變動,請把這當作當時的快照。
| 網站 | HSTS | CSP | 框架控制 | nosniff | Referrer | Permissions |
|---|---|---|---|---|---|---|
| github.com | 存在 | 需檢查 | 存在 | 存在 | 存在 | 未提供 |
| ipnixa.com | 存在 | 需檢查 | 存在 | 存在 | 存在 | 存在 |
| www.wikipedia.org | 存在 | 未提供 | 未提供 | 未提供 | 未提供 | 未提供 |
| www.google.com | 未提供 | 僅回報 | 存在 | 未提供 | 未提供 | 未提供 |
| example.com | 未提供 | 未提供 | 未提供 | 未提供 | 未提供 | 未提供 |
解讀範例:需檢查不等於薄弱
GitHub的政策將指令碼限制在自家的資源主機與特定雜湊值,相當嚴格。它被標示為「需檢查」,只是因為其style-src允許'unsafe-inline',而規則會在整個政策中尋找這個關鍵字。內嵌樣式的風險遠低於內嵌指令碼,因此這是刻意的取捨,而不是漏洞。
本站被標示為「需檢查」的原因不同:我們的政策只有frame-ancestors 'none',能阻擋框架嵌入,但不限制指令碼。我們在此如實呈現結果。
Google首頁以Content-Security-Policy-Report-Only傳送其指令碼政策,只回報違規而不封鎖,且這次回應沒有傳送HSTS;大型網站可透過瀏覽器預先載入清單等其他方式強制使用HTTPS。Wikipedia入口頁傳送了很長的HSTS max-age,該頁面的其他標頭則很少。這些都無法說明這些網站整體是否安全,只能顯示每個回應要求瀏覽器啟用哪些防護。
為自己的網站加入標頭
每次只加入一個標頭,重新載入網站,確認頁面、登入、嵌入影片與付款表單仍正常運作後,再加入下一個。
- 先從風險較低的標頭開始:X-Content-Type-Options: nosniff、Referrer-Policy: strict-origin-when-cross-origin,以及X-Frame-Options: DENY(除非你的頁面必須被其他網站以框架嵌入)。
- 加入HSTS時先用較短的max-age,例如300;確認每個子網域都能透過HTTPS正常運作後,再提高到31536000。只有在所有子網域都支援HTTPS時,才加入includeSubDomains。
- 撰寫Content-Security-Policy,並先以Content-Security-Policy-Report-Only傳送。收集違規報告或觀察瀏覽器主控台,修正或允許合法的來源後,再改用強制執行的標頭。
- 加入Permissions-Policy,列出你不使用的高權限功能,例如camera=(), microphone=(), geolocation=()。
- nginx使用帶有always旗標的add_header,Apache使用Header always set;靜態網站代管或CDN則使用平台的標頭檔案或回應標頭規則。
- 再次執行IPNixa標頭檢查。每個缺少的標頭都會附上可直接複製的nginx、Apache或_headers檔案設定。
HSTS預先載入與其他注意事項
HSTS預先載入清單內建於瀏覽器中,因此連第一次造訪也會使用HTTPS。提交網域需要至少一年的max-age、includeSubDomains與preload指令,而移除後要數個月才會傳達到使用者。只有在每個子網域(包括內部子網域)都會持續使用HTTPS時,才提交。
X-XSS-Protection已過時;現代瀏覽器會忽略它,並由CSP取代。跨來源隔離標頭(Cross-Origin-Opener-Policy、Cross-Origin-Embedder-Policy與Cross-Origin-Resource-Policy)不在檢查工具的評定範圍內,因為只有使用共用記憶體等功能的網站才需要它們,而且啟用後可能封鎖第三方嵌入內容。
常見問題
缺少標頭代表網站不安全、不該造訪嗎?
不是。標頭是在瀏覽器端針對特定攻擊增加防護。沒有這些標頭的網站仍可能管理良好,全部具備的網站也可能有其他缺陷。請把結果當作網站擁有者的檢查清單,而不是給訪客的判定。
為什麼瀏覽器顯示的標頭,檢查工具卻沒看到?
網站可能依頁面、國家、登入狀態或CDN節點傳回不同的標頭。檢查工具讀取的是你輸入網址的單次回應,從Cloudflare網路取得,且不帶Cookie。
該用X-Frame-Options還是frame-ancestors?
CSP中的frame-ancestors是較新的控制方式,可以允許特定網站。同時傳送X-Frame-Options可兼顧較舊的瀏覽器;兩者同時存在時,目前的瀏覽器會依frame-ancestors處理。
可以檢查需要登入的頁面嗎?
不行。檢查工具不會傳送Cookie或憑證,也會拒絕私有與本機位址。若是需要登入或位於私人網路的頁面,請從瀏覽器的開發人員工具或curl -I複製原始回應標頭,再貼到檢查工具中;貼上的標頭會在你的瀏覽器中分析。