接獲通知,網站目前未設定 script-src、object-src 明確指向引用來源,建議加上以強化安全性,並貼心附上 參考文件 及設定範例:

Allow everything but only from the same origin
default-src 'self';
Only Allow Scripts from the same origin
script-src 'self';

之前有設定 X-Frame-Options 及 Content-Scurity-Policy(CSP)的經驗,這回照著設定範例在 HTTP Response Header 再加兩個 'self',就功德圓滿,網站瞬間更安全?

等等,沒搞清楚就動手瞎調,當心網站還沒變安全就先掛點。

依據之前的經驗,許多資安設定像「藥」,加減帶點毒性,使用前應先詳讀仿單,認清藥性、療效依據及副作用,評估自身體質後再服用,以防毒發身亡。

CSP 主要用於防止 XSS 攻擊,整理剛才提到的幾個名詞:

  1. default-src 參考
    CSP 有一連串的 *-src 設定,default-src 可指定預設值,一口氣影響 child-src、connect-src、font-src、frame-src、img-src、manifest-src、media-src、object-src、prefetch-src、script-src、script-src-elem、script-src-attr、style-src、style-src-elem、style-src-attr、worker-src。
    前面範例指定 'self' 只是指定預設值,一般會搭配 script-src、img-src... 等逐一覆寫各項設定,若只寫 default-src 'self',將全面禁止載入任何來自其他網站的 js、css、font、img、IFrame,除非 100% 確定網站所有內容都由自身提供,八成會出事。
  2. script-scr 參考
    若網站用到的所有 .js 都放在自家網站,未使用 CDN 也沒載入 Google 或社群網站外掛,可寫 script-src 'self'
    若用到外部 .js,需清查後一併列舉,寫成 script-src 'self' https://xxx.yyy.zzz https://aaa.bbb.ccc
    要注意 js 載入其他 js 的狀況,例如:reCaptcha www.google.com/api.js 會引用 www.gstatic.com/recaptcha__zh_tw.js,二者都要加上去。
    如果網頁有用到 <script> ... </script> Inline JavaScript 區塊,需加上 'unsafe-inline',有用到 eval() 等字串轉指令功能,則要加上'unsafe-eval',否則部分 JavaScript 可能會失效。若不想開放 unsafe-inline,可使用 nonce 或為 Inline Script 產生雜湊
  3. object-src 參考
    用於限制 object、embed、applet 來源,這個年代應該沒什麼網頁在用這類物件,沒有的話可安心設定 'self' 或 'none'

來實際演練一下。用之前我不是機器人版 reCAPTCHA 當範例,從 F12 偵錯工具可觀察到網站會從 www.google.comwww.gstatic.comfonts.gstatic.com 下載 js、css、png、woff2:

試著加上 Content-Security-Policy: script-src 'self'

瀏覽器噴出 js 阻擋錯誤 Refused to load the script 'https://www.google.com/recaptcha/api.js' because it violates the following Content Security Policy directive: "script-src 'self'". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.

以 reCaptcha 網頁為例,需依賴 Google 的 JS 方能運作,故得列舉 www.google.comwww.gstatic.com,寫成 script-src 'self' https://www.google.com https://www.gstatic.com,以便網頁能正常載入外部 JS。(更新:限定 www.google.com 會有風險,請見文末說明及留言)

如果加上 default-src 會怎麼樣,例如:default-src 'self';script-src 'self' https://www.google.com https://www.gstatic.com,如下圖,js 成功載入,但相關 css、圖檔全部被擋,不意外地網頁壞給你看。

最後,推薦 DEVCORE 的這篇 - Content-Security-Policy - HTTP Headers 的資安議題 (2) by Bowen Hsu,有一些深入說明及實務技巧,值得一看。

[2022-06-14 更新]感謝讀者 huli 補充,開放 https://www.google/com 存在透過 Google JSONP Endpoint 進行 XSS 攻擊的危險(前題是網站存在 HTML Injection 漏洞),如要更嚴謹可將開放對象細到 https://www.google.com/recaptcha。另外 Google 有個 CSP 檢測工具可協助檢測 CSP 設定的安全性。

Introduction to CSP default-src and script-src settings.


Comments

# by huli

話說在設定 script-src 的時候其實有陷阱,舉例來說,文中提到的 https://www.google.com 是不安全的,因為在這個網址上有個很容易查到的 JSONP endpoint:https://www.google.com/complete/search?client=chrome&q=hello&callback=alert#1 如果我能夠在你網站上找到 HTML injection,就可以這樣寫:<script src="https://www.google.com/complete/search?client=chrome&q=hello&callback=alert#1"></script> 來 bypass CSP Google 有出一個小工具幫忙檢測 CSP 規則的安全性:https://csp-evaluator.withgoogle.com/ ,會幫你抓出來這些細節上的小問題,建議設成更嚴格的 https://www.google.com/recaptcha 之類的,來擋住這種已知的 bypass

# by Jeffrey

to huli, 感謝專業補充,已加註於文章。

# by 布丁

長知識了

# by Justin

請問一下, 這句話 "若不想開放 unsafe-eval,可使用 nonce 或為 Inline Script 產生雜湊。" 是正確的嗎? 我參考 https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#unsafe_eval_expressions, 沒寫到 nonce 可以開放, 實測也是不行。

# by Jeffrey

to Justin,重新想了一下,應該是"若不想開放 unsafe-inline,..."才對,謝謝指正。

Post a comment