企業網站的安全標頭,先把 6 項設好:HSTS(強制 HTTPS)、CSP(內容安全政策)、X-Frame-Options(禁止被別站嵌入)、X-Content-Type-Options(禁止瀏覽器猜檔案類型)、Referrer-Policy(控制來源網址外流)、Permissions-Policy(關閉用不到的相機、麥克風、定位)。再把會洩漏版本的 X-Powered-By 拿掉。這幾項都是伺服器回應時附帶的一行文字,不改網頁內容、不花授權費,但設錯的代價很具體:HSTS 涵蓋到沒有憑證的子網域,那個子網域就打不開;CSP 太嚴,追蹤碼、選單或表單會無聲失效。
這篇用本站(mani.tw)自己的設定當例子,數值都是 2026 年 11 月 3 日用 curl 實測的回應。文中說明每一項在防什麼、我們設了什麼值、為什麼 CSP 刻意先不加 script-src,以及上線前怎麼驗。伺服器端的入侵防護與備份是另一個題目,見WordPress 被駭怎麼救;憑證本身的選擇見SSL 憑證免費和付費差在哪。
6 個網站安全標頭各管什麼?本站實測值一覽
安全標頭是伺服器告訴瀏覽器「這個網站要用什麼規矩對待」的指示。瀏覽器照做,攻擊就少一條路;沒設,瀏覽器就用寬鬆的預設行為。下表是本站目前的設定:
| 標頭 | 防什麼 | 本站的值 | 設錯或漏設的後果 |
|---|---|---|---|
| Strict-Transport-Security(HSTS) | 訪客第一次輸入 http 時被攔截、降級成明文連線 | max-age=31536000; includeSubDomains; preload | 漏設:http 那一段仍可被竄改;涵蓋範圍設太大:沒有憑證的子網域整個打不開 |
| Content-Security-Policy(CSP) | 網頁被插入惡意腳本、被別站嵌入、表單被導到外部網址 | frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none' | 太嚴:GA4、客服對話框、地圖、表單送出失效;太鬆:只是看起來有做 |
| X-Frame-Options | 點擊劫持:別的網站把你的頁面透明疊在按鈕底下,騙訪客點擊 | SAMEORIGIN | 設成 DENY:自己站內用 iframe 嵌自己的頁面也會被擋 |
| X-Content-Type-Options | 瀏覽器把上傳的文字檔或圖片「猜」成腳本來執行 | nosniff | 主機回錯檔案類型時,CSS 或 JS 會被瀏覽器拒絕載入,版面整個跑掉 |
| Referrer-Policy | 點出站外時,完整網址(含查詢參數)被帶給對方網站 | strict-origin-when-cross-origin | 設成 no-referrer:合作夥伴與廣告平台的報表看不到你這個來源 |
| Permissions-Policy | 頁面(或被嵌入的第三方內容)偷偷呼叫相機、麥克風、定位 | camera=(), microphone=(), geolocation=(), payment=(), usb=() | 網頁真的需要定位或相機時,功能會直接被瀏覽器關掉 |
2026-11-03 以 curl -sSI 對 https://mani.tw/ 連測兩次,兩次結果相同;另外對不存在的網址(404)與圖片檔各測一次,6 項標頭都在。
另外兩件事一起說明:
- 拿掉 X-Powered-By:PHP 預設會在回應裡寫出版本號。本站 2026 年 8 月的資安檢查發現回應帶著 PHP 版本,之後在
.htaccess用Header always unset X-Powered-By移除。版本號本身不是漏洞,但等於幫掃描程式先篩選目標。 - X-XSS-Protection 不必再加:這是舊瀏覽器內建過濾器的開關,主流瀏覽器已經移除該功能,網路上的舊教學還常列它。真正擋跨站腳本的是 CSP 的
script-src,下面第三節會談。
HSTS 與 preload:效果最直接,也最難回頭
網站就算已經把 http 301 轉址到 https,訪客第一次輸入「mani.tw」時,瀏覽器送出的第一個請求仍是 http,這一段沒有加密,在公共 Wi-Fi 上有機會被攔截。HSTS 的作用是:瀏覽器收過一次這個標頭,之後 max-age 期間內,連 http 都不送,直接改走 https。
三個參數要分開看:
- max-age:記住多久,單位是秒。本站設 31536000,也就是 365 天。
- includeSubDomains:所有子網域一併強制 https。這一項風險最大:公司若有某個子網域(例如舊的後台、測試站、內部系統)沒有有效憑證,瀏覽器會直接拒絕連線,訪客連「仍要繼續」的按鈕都沒有。
- preload:表示同意把網域寫進瀏覽器內建的 HSTS 清單。進了清單之後,連「第一次」都不用等,新裝的瀏覽器一開始就只走 https。
本站 2026 年 11 月 3 日查詢 hstspreload.org 的狀態是 preloaded,也就是 mani.tw 已在清單內。申請 preload 的條件是:有效憑證、http 轉到同一主機的 https、所有子網域都走 https,以及 HSTS 標頭的 max-age 至少一年並帶 includeSubDomains 與 preload。
preload 是單行道,申請前先盤點子網域
進了瀏覽器內建清單,想撤出要另外申請移除,並等各瀏覽器陸續發布新版本才會生效,時間以月計算,這段期間沒有憑證的子網域在新舊瀏覽器上都打不開。建議順序:先把每個子網域的憑證補齊,HSTS 先用短的 max-age(例如一週)上線觀察,沒問題再拉長到一年,最後才加 preload 送出申請。
還有兩個常被誤會的細節。第一,HSTS 只在 https 的回應裡才有效;本站 http 的 301 回應雖然也帶著這個標頭,但依標準規定,瀏覽器會忽略從 http 收到的 HSTS,真正生效的是 https 那一次。第二,Apache 系的 Header set 在部分錯誤回應不會附上標頭,要涵蓋所有回應得寫成 Header always set。本站 HSTS 用的是前者,實測 404 頁仍帶著標頭,但不同主機軟體的行為不一定相同,所以驗收時一定要連錯誤頁一起測。
CSP 為什麼本站刻意不加 script-src?
CSP 是安全標頭裡功能最多、也最容易設壞的一項。它用「指令」逐項列出允許的來源,例如腳本只能從哪裡載入、表單只能送到哪裡、頁面能不能被嵌入。本站目前只上了 4 個指令:
| 指令 | 本站的值 | 作用 | 要注意的情況 |
|---|---|---|---|
| frame-ancestors | 'self' | 只有自己的網站可以用 iframe 嵌入本站頁面,作用等同 X-Frame-Options 的新版寫法 | 新瀏覽器兩者都看得到時以 frame-ancestors 為準,X-Frame-Options 留給舊瀏覽器 |
| base-uri | 'self' | 防止被插入的 base 標籤把頁面上所有相對連結改到別的網域 | 一般網站不會用到外部 base,幾乎沒有副作用 |
| form-action | 'self' | 表單只能送回自己的網域,被竄改的表單無法把資料送到外部 | 表單要直接送到金流、問卷或行銷平台時,要把那個網域加進來,否則按送出沒有反應 |
| object-src | 'none' | 禁止 Flash 這類外掛物件 | 現代網站已不需要,安全的起手式 |
真正擋跨站腳本(XSS)的是 script-src:只允許指定來源的腳本執行,攻擊者塞進頁面的腳本就跑不起來。問題在於內嵌腳本。2026 年 11 月 3 日本站首頁的原始碼裡,有 4 段會執行的內嵌 <script>(GA4 追蹤設定就在其中)、2 段結構化資料、5 個 <style> 區塊與 19 處 style 屬性。這時加上 script-src 只有兩條路:
- 不允許內嵌:那 4 段腳本立刻被瀏覽器擋下,GA4 不再記錄、互動功能失效,而且頁面看起來一切正常,不會有人第一時間發現。
- 加上
'unsafe-inline':頁面恢復正常,但攻擊者插入的內嵌腳本也一樣被允許。這種 CSP 對 XSS 幾乎沒有防護力,只是讓檢測工具的分數變好看。
所以本站 2026 年 8 月加 CSP 時的決定是:先上不影響既有頁面的 4 個指令,script-src 等內嵌腳本抽成外部檔之後再加。要走到那一步,順序是:
- 把內嵌腳本搬成外部 .js 檔;真的必須內嵌的,改用每次回應都不同的 nonce 或內容雜湊值放行。
- 先用
Content-Security-Policy-Report-Only送出新政策:瀏覽器只回報違規、不真的阻擋,觀察一段時間,確認第三方服務(GA4、地圖、影片、客服)的網域都列齊。 - 違規回報只剩下可以解釋的項目,才改成正式的
Content-Security-Policy。
如果網站是用 WordPress 或套版系統,佈景與外掛常自帶大量內嵌腳本,完整的 script-src 更難做到,這時先把 4 個指令上好、外掛更新紀律做好,比追求滿分的 CSP 實際。
安全標頭設錯的 6 種後果與上線前驗收
安全標頭出問題時,畫面通常不會報錯,只是某個功能悄悄不動了。下表是實務上比較常碰到的狀況:
| 設錯的方式 | 會看到什麼 | 怎麼避免 |
|---|---|---|
| HSTS 加了 includeSubDomains,但有子網域沒憑證 | 那個子網域在瀏覽器上完全無法開啟 | 上線前列出所有子網域,逐一用 https 開過 |
| CSP 加了 script-src 卻漏列第三方網域 | GA4 數字掉到接近零、地圖或客服對話框消失 | 先用 Report-Only 觀察,看瀏覽器開發者工具的主控台有沒有違規訊息 |
| CSP form-action 只寫 'self',表單卻要送外部服務 | 按送出沒反應,客人以為送出了 | 把每張表單的送出目標列出來,逐一實際送一次 |
| 同一個標頭在 .htaccess 與程式裡各設一次 | 回應出現兩份 CSP,瀏覽器兩份都套用,結果比任何一份都嚴 | 決定只在一個地方設,用 curl 看有沒有重複 |
| nosniff 搭配錯誤的檔案類型設定 | CSS 或 JS 被拒絕載入,版面變成純文字 | 確認 .css 回 text/css、.js 回 JavaScript 類型 |
| Permissions-Policy 關掉了網頁真正要用的功能 | 「我的位置」按鈕或線上拍照功能沒反應 | 先盤點網頁用到哪些裝置權限,只關用不到的 |
驗收比較可靠的方法是直接看伺服器的回應,不要只看設定檔。下面這行會列出首頁回應裡的安全標頭(把 mani.tw 換成你的網域):
curl -sSI https://mani.tw/ | grep -iE 'strict-transport|content-security|x-frame|x-content-type|referrer-policy|permissions-policy|x-powered-by'
驗收時有三個習慣:
- 不只測首頁:至少再測一個不存在的網址(看 404 有沒有帶標頭)、一張圖片、一支 CSS,以及 http 開頭的網址。檢查轉址時不要加
-L,否則看到的是最後一站,轉了幾次看不出來,理由見網站改版網址會變怎麼辦。 - 同一個網址測兩次:本站 2026 年 8 月補標頭時,有一次 curl 只回傳了其中兩項,看起來像其他標頭全部消失;加上避開快取的參數重測兩次,6 項都在,前一次只是暫時性的回應。標頭類的結論,重測第二次才算數。
- 實際操作關鍵功能:標頭改完之後,送一次詢價表單、看 GA4 即時報表有沒有記到、點一次站內嵌入的影片或地圖。表單的其他防護見官網表單垃圾訊息怎麼擋。
請廠商或主機商確認安全標頭時,問這 6 件事
一、6 項安全標頭目前各設了什麼值,設在 .htaccess、主機設定還是程式裡?二、HSTS 有沒有 includeSubDomains,公司所有子網域是否都有有效憑證?三、CSP 有沒有 script-src,沒有的話打算何時、用什麼方式補上?四、表單、金流、地圖、客服等第三方服務的網域有沒有列進 CSP?五、回應裡還有沒有 X-Powered-By 這類版本資訊?六、改標頭之後誰負責驗收,驗了哪些網址?
安全標頭適合在建站時就一起規劃:網頁設計階段少用內嵌腳本,日後補 script-src 就容易;上線後由網站代管在每次加第三方服務、改表單時一併檢查 CSP。瑪尼國際成立於 2004 年,深耕逾 20 年、服務逾 500 家企業,網站設計、主機與上線後的維護由同一組人負責,這就是我們的一條龍服務。
常見問題
Q:網站安全標頭會影響 SEO 排名嗎?
安全標頭本身不是排名因素,Google 不會因為多設了 CSP 或 X-Frame-Options 就提高排名。會影響的是設錯的後果:HSTS 涵蓋到沒有憑證的子網域會讓頁面打不開,CSP 太嚴會讓追蹤碼、選單或表單失效,這些才會間接傷到流量與詢價。
Q:安全標頭的 CSP 一定要加 script-src 才有用嗎?
script-src 是 CSP 防範跨站腳本(XSS)的核心,但網站若還有大量內嵌腳本,加了就得開 unsafe-inline,防護力會大打折扣。比較務實的做法是先上 frame-ancestors、base-uri、form-action、object-src 這幾項不影響既有頁面的設定,再把內嵌腳本抽成外部檔,用 Report-Only 模式觀察一段時間後才正式加上 script-src。
Q:虛擬主機可以自己設定安全標頭嗎?
多數 Linux 虛擬主機可以在網站根目錄的 .htaccess 用 Header 指令設定,不需要主機商開權限;也可以在 PHP 程式裡用 header() 輸出。兩邊不要重複設同一個標頭,否則瀏覽器可能同時套用兩份,CSP 會變得比預期嚴格。設定完要用 curl 或瀏覽器開發者工具確認首頁、錯誤頁與圖片檔都帶著標頭。