Contents

CSP 網頁安全性設計

CSP 是 Content Security Policy 的縮寫,主要用途是告訴瀏覽器「這個頁面允許載入哪些資源、允許哪些腳本行為」。平常如果只把它當成安全掃描報告裡的一個名詞,很容易低估它對前端行為的實際影響。

發生原因

網頁吃不到CSS,用開發者工具看網路擷取到 JS、CSS都抓到404,發現導向內容為 HTTPS,程式碼都沒有做任何調整設定。

https://i.imgur.com/sgOYMF8.png
https://i.imgur.com/Uzg118R.png
https://i.imgur.com/IHGKdIw.png
https://i.imgur.com/XNStivs.png

這篇主要整理我在查問題時特別有感的一個點:有些資源莫名其妙被改走 HTTPS,背後未必是程式碼寫了轉址,而可能是 CSP 在作用。

CSP 在做什麼

CSP 可以透過 HTTP 回應標頭,或 HTML 的 meta 標籤設定。它的功能很多,像是限制腳本來源、圖片來源、iframe 來源,或調整瀏覽器對不安全內容的處理方式。

其中一個很容易影響行為的指令是:

1
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">

upgrade-insecure-requests 會發生什麼事

這個指令會要求瀏覽器把頁面中的 HTTP 資源請求,自動升級成 HTTPS。也就是說,原本你寫的是:

1
<script src="http://example.com/app.js"></script>

瀏覽器可能會直接改成用 HTTPS 去抓。

如果對方站台根本沒有提供 HTTPS,結果就會是資源載不到、樣式不見、腳本失效,看起來很像前端壞掉。

為什麼這件事容易誤判

因為它不是你在 JavaScript 裡明寫 location.href = ...,也不是後端 301/302 轉址,所以第一眼很難聯想到是 CSP。實務上常見誤判方向有:

  1. 以為 Nginx 或 IIS 偷偷做了 HTTPS 導轉。
  2. 以為某個 base URL 設定錯誤。
  3. 以為第三方 CDN 自己有問題。

但其實只是頁面內或 response header 帶了 CSP 指令。

要怎麼排查

我自己會先看這幾個地方:

  1. 開發者工具的 Network 面板,確認請求是不是被升級成 HTTPS。
  2. Response Headers 裡有沒有 Content-Security-Policy。
  3. HTML 原始碼裡有沒有 meta http-equiv="Content-Security-Policy"

如果只在 localhost 正常、放到某些環境就出問題,也很值得懷疑是不是不同環境回了不同 CSP。

怎麼處理比較好

如果系統本來就要全面 HTTPS,那 upgrade-insecure-requests 很合理;但如果目前還存在只支援 HTTP 的內部資源,這個設定就要很小心。

常見做法有兩種:

  1. 先把所有資源改成真正可用的 HTTPS。
  2. 暫時拿掉這個指令,避免瀏覽器自動升級請求。

小結

CSP 不只是安全設定,也會直接改變瀏覽器怎麼載入資源。尤其 upgrade-insecure-requests 很容易讓 HTTP 資源在你沒注意時被升級成 HTTPS。遇到這類詭異問題時,除了查程式碼本身,也要把 CSP 一起納入排查範圍。