本篇文章更新時間:2024/05/30
如有資訊過時或語誤之處,歡迎使用 Contact 功能通知。
一介資男的 LINE 社群開站囉!歡迎入群聊聊~
如果本站內容對你有幫助,歡迎使用 BFX Pay 加密貨幣 或 新台幣 贊助支持。
上週台積電的合作公司網站檢測出現了這個 Content Security Policy(CSP)缺失項目要修正更新。
調整了第一版掛上去後,又檢測出第一版的設定不夠安全,要去除使用 script-src
中的 unsafe-inline
這個方法。
先前處理星展銀行的開發案都沒這麼嚴格勒!
而且由於是從 HTTP Header 來檢測,也不能使用 HTML Meta 元素來覆蓋,第一時間取消使用 script-src
中的 unsafe-inline
方法會造成不少 JavaScript 有問題。
要解決這樣的問題就是要搭配使用 nonce-XXX
這樣的做法,來讓伺服器回傳的關鍵字匹配網頁中 Script 元素使用的關鍵字,使瀏覽器認定這是安全的內容。
不過,WordPress 網站如果不是全部網站主題與外掛都是自行開發的話,那 JavaScript 引入的方式就可能超多種。
內建呼叫引入的方法在 v5.7
後已經有提供客製化屬性的功能
wp_script_attributes ,如下範例:
function mxp_wp_script_attributes( $attr ) {
$attr['nonce'] = 'mxp_tw';
return $attr;
}
add_filter( 'wp_script_attributes', 'mxp_wp_script_attributes' );
但這樣還是無法讓所有外掛提供的引用 JavaScript 元素滿足掛上 nonce
的條件。
所以最後是直接從「頁面輸出時」來直接全面替換上這個關鍵字,方法如下:
function mxp_add_nonce_to_script_tags($buffer) {
// 建立 DOMDocument 方法
$dom = new DOMDocument();
// 讀取輸出頁面 HTML 內容
@$dom->loadHTML('' . $buffer);
// 取得全部 Script 元素的方法
$scripts = $dom->getElementsByTagName('script');
// 將所有元素都補上 nonce 屬性
foreach ($scripts as $script) {
$script->setAttribute('nonce', 'mxp_tw');
}
// 輸出 HTML
$newBuffer = $dom->saveHTML($dom->documentElement);
return $newBuffer;
}
function mxp_add_nonce_to_scripts() {
ob_start('mxp_add_nonce_to_script_tags');
}
add_action('template_redirect', 'mxp_add_nonce_to_scripts');
這樣就順利通過瀏覽器的驗證了~
不過當然那個「mxp_tw
」關鍵字要做到動態,就是另一個應用層面來解決的事。每次請求都需要產生並且帶入標頭輸出。可以搭配使用 wp_headers 這個勾點來呼叫。
下方順便筆記本次設定的 CSP 標頭:
frame-ancestors 'self';
default-src 'self' blob: data: www.google-analytics.com ;
script-src 'self' 'unsafe-eval' 'nonce-mxp_tw' *.optimole.com *.googleapis.com www.googletagmanager.com static.addtoany.com instant.page www.google-analytics.com;
font-src 'self' data: fonts.gstatic.com;
img-src 'self' data: secure.gravatar.com *.optimole.com www.googletagmanager.com;
frame-src 'self' static.addtoany.com;
style-src 'self' 'unsafe-inline' fonts.googleapis.com ;
object-src 'none';
base-uri 'self';
驗證 CSP 的設定與安全性可以參考 Google 這個工具: CSP Evaluator
Google 自己的工具判定 GA / GTM 自己的服務也是不安全,這點公正倒是很有趣。
對於引入 gtag.js
的 CSP nonce 作法,Google 這份文件 搭配內容安全政策使用代碼管理工具 也有寫得滿清楚的可以參考。