Defaults.Exposed

Defaults.Exposed修復 › 內容安全策略(CSP)

如何修復 內容安全策略(CSP)

內容安全策略是你的網站交給每個訪客瀏覽器的一條安全規則,明確告訴它哪些程式碼獲准執行。沒有它,一旦有惡意東西落到頁面上——透過一個留言框、一個被黑的外掛、或一個第三方腳本——瀏覽器就會隨意執行它,包括在你客戶輸入時悄悄盜取卡號和密碼的程式碼,而那把鎖還顯示著。

對您業務的關鍵影響: 你的網站一旦被篡改,惡意程式碼就能在一切看起來完全正常的情況下,直接從你自己的結帳頁面讀走客戶的支付卡和登入資訊——留給你的是退款、欺詐索賠、一樁須上報的資料外洩,以及一個大客戶安全團隊用來擱置或扼殺生意的檢查失敗。

這會讓您付出什麼代價

為什麼它重要。 那把鎖證明到你網站的連線是私密的,但它對訪客上了頁面之後哪些程式碼執行毫無控制。內容安全策略正是那個有控制的防護——它告訴瀏覽器忽略任何並非來自你信任來源的腳本,於是一個被篡改的欄位、廣告或外掛,無法被變成盜取你客戶金錢和資料的工具。它是你評分卡上的一項計分檢查,值實打實的分數,也是一次專業安全稽核最先查的東西之一。

這是什麼,大白話版

當有人訪問你的網站時,他的瀏覽器下載你的頁面並執行上面的任何程式碼——那些讓選單下拉、按鈕運作、支付表單提交等等的腳本。預設情況下,瀏覽器信任所有這些。它無從知道哪些程式碼真正是你的、哪些是別人偷偷塞進來的。

一個內容安全策略(常簡稱 CSP)是你的網站附加到每個頁面上的一份簡短規則清單,告訴瀏覽器:「只執行來自我批准的這些來源的程式碼,其餘一概拒絕。」 這是一家誰都放進去的夜店和一家門口有賓客名單的夜店之間的區別。

它之所以如此重要,是因為網站不斷被篡改——並不總是透過黑掉你的伺服器,而是透過多數網站留著的那些後門:一個留言欄位、一個搜尋框、一個過時的外掛、一個用於廣告或分析的第三方腳本,或一個聊天小工具。如果攻擊者哪怕把一行他自己的程式碼弄到你的某個頁面上,瀏覽器就會把它當作你的來執行。從那裡它能讀走你客戶輸入的一切——卡號、密碼、地址——並悄悄送往別處。內容安全策略透過拒絕執行任何來自你未批准來源的東西,關上那扇門。

這會讓你付出什麼代價

這不抽象。內容安全策略所防止的攻擊——注入頁面、從你自己客戶那裡盜取資料的程式碼——是有記錄以來一些最大的刷卡外洩的幕後元凶。下面是它對一家普通企業往往如何上演:

它到底是什麼(細節)

一個內容安全策略以一個 HTTP 回應標頭的形式傳遞——一行你的 Web 伺服器隨每個頁面發送的內容。它的值是一組指令,每條命名一類內容及其允許的來源。例如:

Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; frame-ancestors 'self'

用大白話說,這是:預設只從我自己的網站載入東西;只執行來自我自己網站的腳本;不允許任何老式外掛;並且不讓其他網站把我的網站嵌進一個框架裡。

「好」長什麼樣。 我們的檢查不只是看標頭是否存在——它像一個安全審查者那樣,逐條指令地讀這個策略,給它實際有多強評分。一個強壯的策略:

一個存在卻依賴 'unsafe-inline''unsafe-eval' 或萬用字元的策略仍會得分很低——因為實際上它提供的真實保護很少。目標是一個收緊的策略,而不只是隨便一個策略。

如何修復(免費,約 1–2 小時)

把這個交給你的 IT 人員或運營你網站的人——修復本身完全免費。 我們只對長期監控它是否保持就位、保持正確收費;打開它分文不取。它要花一兩個小時而非幾分鐘的原因,是那個防止它不小心攔掉你自己網站某些部分的小心試運行步驟。

  1. 以僅回報模式起步——暫不強制執行。 新增一個 Content-Security-Policy-Report-Only 回應標頭。它觀察並記錄「會被」攔掉什麼,卻不真正攔截任何東西,於是即時網站照常運作,同時你了解每個頁面真正依賴什麼。(重要:僅回報本身不給訪客任何保護——它只是穩妥的第一步。)

  2. 從你網站實際使用的東西出發構建策略。 審查回報,找出每一個合法的腳本、樣式、字型和圖片來源——你自己的網域、你的分析、你的支付服務商、你的字型託管、你的聊天小工具——把它們列為允許的來源。一個紮實的起點是 default-src 'self' 加上你真正使用的可信第三方的明確條目。

  3. 避開那些擊穿整個意義的漏洞。 遠離腳本的 'unsafe-inline''unsafe-eval',並避免腳本的萬用字元來源如 * 和光禿禿的協定如 https:——這些重新打開了策略本該關上的那個缺口。在內嵌腳本不可避免的地方,使用一個 noncehash,讓只有你特定批准的程式碼才執行。

  4. 鎖死框架嵌入和外掛。 加上 frame-ancestors 'self'(這也阻止其他網站嵌入你的來哄騙你客戶,並滿足相關的點擊劫持檢查)和 object-src 'none' 來攔截基於遺留外掛的攻擊。

  5. 從僅回報切換到強制執行。 一旦回報乾淨、網站運作,就把標頭名稱從 Content-Security-Policy-Report-Only 改成 Content-Security-Policy這一步才真正交付保護——單有一個僅回報策略並不交付,也不會通過檢查。

    你在哪裡設這個標頭取決於你的平台:

    • Cloudflare: Rules → Transform Rules → Modify Response Header → 設 Content-Security-Policy。(你也可以用 Cloudflare 做僅回報試運行。)
    • Nginx: add_header Content-Security-Policy "default-src 'self'; script-src 'self'; object-src 'none'; frame-ancestors 'self';" always;
    • Apache: Header always set Content-Security-Policy "default-src 'self'; script-src 'self'; object-src 'none'; frame-ancestors 'self';"
    • IIS(web.config): 新增一個名為 Content-Security-Policy 的自訂 HTTP 回應標頭,以策略為其值。
    • Google Workspace / Microsoft 365: 這些運行的是你的郵件,不是你的公開網站,所以策略設在你網站實際託管的地方(上面的 Cloudflare 或你的 Web 主機),而不是你的郵件管理後台。
  6. 重新檢測你的網域,確認策略現在顯示為已打開、且在強制執行,沒有削弱性的漏洞。

常見錯誤

常見問題

我不懂技術——這個我自己能搞定嗎?

你不需要懂細節。這是由運營你網站或主機的人新增的一個設定,而在 Cloudflare 這樣的服務上它基本是有引導的。把下面的「如何修復」一節交給他們。它免費;唯一要當心的是,它應當先以僅觀察的試運行小心鋪開,以免不小心攔掉你自己網站的某些部分——而那恰恰是這些步驟所涵蓋的。

我已經有那把鎖和一張 SSL 憑證了——我的網站不就安全了嗎?

那把鎖保護你頁面的「傳輸」;它不管頁面「裡面」執行什麼。一旦惡意程式碼落到頁面上——透過一個被黑的外掛、一個被攻陷的廣告,或一個被注入的欄位——那把鎖不會阻止它盜取資料。內容安全策略是那個從一開始就限制允許執行什麼的層。它們保護不同的東西,你兩個都要。

打開這個會搞壞我的網站嗎?

如果一次性激進地打開就有可能,因為它可能攔掉你實際使用的合法腳本。這正是為什麼標準做法是先以「僅回報」試運行模式起步,它觀察而不攔截,修好它標記的任何東西,然後才強制執行。這樣做是安全的——而這個試運行步驟已內建在下面的修復裡。

我們已經把它放在「僅回報」模式了——這就被覆蓋了嗎?

沒有,而這是最常見的虛假安全感。僅回報模式觀察並記錄「會被」攔掉什麼,但它什麼都不攔——訪客得到的真實保護為零。它只是穩妥的第一步。我們的檢查只給僅回報一個真實策略的一小部分信用,並且不會把它記為通過。你只有切換到強制執行模式後才受保護。

這影響我們的評分,還是只是建議性的?

它影響你的評分。內容安全策略檢查是計分的,在網站安全類別中最高值 25 分。一個缺失或孱弱的策略被標為高嚴重度,會拉低你的評分——而它恰恰是一個客戶的安全問卷會問到的那類缺口。

我們的開發者加了一個策略,但分數還是很低——為什麼?

一個策略可以存在卻仍然孱弱。最常見的禍首是像腳本的「unsafe-inline」和「unsafe-eval」之類的漏洞,或萬用字元來源(一個光禿禿的 *),它們重新打開了策略本該關上的那個缺口。我們的檢查逐條指令地讀這個策略,並對那些弱點扣分——一個什麼都允許的策略,得分比沒有策略好不了多少。修復是用 nonce 或 hash 來收緊腳本規則,而不是那些漏洞。