跳到內容

第三階段 — 緩解

第三階段建立 CSD 緩解的前後對比證明。您先在不啟用任何緩解措施的情況下重新執行攻擊以建立基準線,套用緩解措施後,再重新執行相同的攻擊,以證明 CSD 能夠封鎖網路呼叫。繼續之前,第二階段必須已完成——所有 DET 檢查均須通過。

步驟 1:確認無作用中的緩解措施(基準線)

Section titled “步驟 1:確認無作用中的緩解措施(基準線)”

在擷取「前」的快照之前,請確認環境是乾淨的——不應有任何作用中的緩解措施。這可確保基準線攻擊在沒有任何 CSD 封鎖的情況下執行。

Terminal window
curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/mitigated_domains" \
| jq '{count: (.items | length)}'

如果數量不是 0,表示有緩解措施遺留自先前的執行。請在繼續之前將其逐一刪除:

Terminal window
# 刪除已緩解的網域(對每個網域名稱重複執行)
curl -s -X DELETE \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/mitigated_domains/<domain-name>" \
| jq .

<domain-name> 替換為緩解該網域時所使用的 metadata.name(例如 cdn.jsdelivr.netesm.shunpkg.comga.jspm.iohttpbin.orgjsonplaceholder.typicode.com)。如果清理 httpbin.org 後仍有剩餘項目,也請嘗試刪除 www.httpbin.org——部分先前的執行可能以此作為 metadata name。

Terminal window
curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/detected_domains" \
| jq '{total_domains: .domain_summary.totalDomains, domains: [.domains_list[]? | {domain: .domain, category: .category}]}'
檢查項目預期結果狀態
已緩解網域數量0(乾淨的基準線)若為 0 則 PASS,若 > 0 則需清理
已偵測網域數量> 0(第二階段偵測結果存在)若 > 0 則 PASS
外洩網域存在www.httpbin.orgjsonplaceholder.typicode.com若至少出現一個則 PASS

沒有作用中緩解措施的情況下重新執行合併模擬,以擷取新鮮的基準線。這是**「前」的快照**——證明在未套用 CSD 緩解時攻擊能夠成功的證明。

具備瀏覽器自動化工具的 AI 助理可使用與第二階段相同的 initScript(儲存原生 fetch)以程式方式執行攻擊模擬:

  1. 以 initScript 導覽 — 先導覽至 about:blank 以確保乾淨的文件內容(避免先前導覽遺留的舊 initScript),然後使用第二階段 initScript(逐字複製自第二階段 — AI 自動化執行中的程式碼)以 navigate_page 導覽至 http://$F5XC_DOMAINNAME/#/login。此 initScript 儲存原生的 setIntervalclearIntervalfetchconsole.log——由於此時尚無作用中的緩解措施,原生 fetch 參考是正確的
  2. 關閉歡迎橫幅 — 以 press_key 按下 Escape 關閉歡迎橫幅。後續訪問時橫幅可能不會出現(Cookie 已持久化)。Cookie 同意對話框會由 Escape 鍵自動關閉
  3. 等待完成 — 等待 10 秒,讓所有 CDN 腳本載入/錯誤回呼及 fetch promise 解析完成
  4. 擷取證據 — 以 list_console_messages 檢查是否有 [CSD Demo] Simulation complete 及 CDN 載入結果;以 list_network_requests 過濾 scriptfetch 類型,驗證 HTTP 狀態碼(200/201 表示成功)

不具備瀏覽器自動化工具的操作人員可依照與第二階段 — 步驟 8:攻擊模擬相同的程序手動執行模擬:

  1. 導覽至 http://xF5XC_DOMAINNAMEx/#/login
  2. 在電子郵件和密碼欄位中輸入虛擬憑證(勿提交)
  3. 開啟 DevTools——按 F12 並切換至 Console 分頁
  4. 貼上並執行來自觸發偵測的合併偵測腳本
  5. 觀察主控台輸出——所有 CDN 腳本應能載入,且外洩呼叫應以 200/201 回應成功
檢查項目預期結果(緩解前)狀態
CDN 腳本已注入所有 4 個腳本標籤載入——出現 [Supply Chain] Loaded from 訊息,網路分頁顯示 200PASS
外洩 fetch 至 www.httpbin.org網路分頁顯示 200——資料已傳送PASS
外洩 fetch 至 jsonplaceholder.typicode.com網路分頁顯示 201——資料已傳送PASS
主控台輸出[CSD Demo] Simulation completePASS

針對每個已偵測到的網域,向已緩解網域端點發送 POST 請求。第二階段模擬的主要目標是 4 個 CDN 注入網域及任何已偵測到的資料外洩網域。

主要緩解目標(來自合併模擬腳本):

網域角色
cdn.jsdelivr.netCDN 腳本注入
esm.shCDN 腳本注入
unpkg.comCDN 腳本注入
ga.jspm.ioCDN 腳本注入
www.httpbin.org資料外洩端點
jsonplaceholder.typicode.com資料外洩端點

緩解網域(每個網域執行一次):

Terminal window
curl -s -X POST \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
-H "Content-Type: application/json" \
-d '{
"metadata": {
"name": "cdn.jsdelivr.net",
"namespace": "xF5XC_NAMESPACEx"
},
"spec": {
"mitigated_domain": "cdn.jsdelivr.net"
}
}' \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/mitigated_domains" \
| jq .

對每個網域重複執行:

esm.sh
curl -s -X POST \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
-H "Content-Type: application/json" \
-d '{"metadata":{"name":"esm.sh","namespace":"xF5XC_NAMESPACEx"},"spec":{"mitigated_domain":"esm.sh"}}' \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/mitigated_domains" \
| jq .
# unpkg.com
curl -s -X POST \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
-H "Content-Type: application/json" \
-d '{"metadata":{"name":"unpkg.com","namespace":"xF5XC_NAMESPACEx"},"spec":{"mitigated_domain":"unpkg.com"}}' \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/mitigated_domains" \
| jq .
# ga.jspm.io
curl -s -X POST \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
-H "Content-Type: application/json" \
-d '{"metadata":{"name":"ga.jspm.io","namespace":"xF5XC_NAMESPACEx"},"spec":{"mitigated_domain":"ga.jspm.io"}}' \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/mitigated_domains" \
| jq .
# httpbin.org — 使用 www.httpbin.org 作為 mitigated_domain(詳見下方說明)
curl -s -X POST \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
-H "Content-Type: application/json" \
-d '{"metadata":{"name":"httpbin.org","namespace":"xF5XC_NAMESPACEx"},"spec":{"mitigated_domain":"www.httpbin.org"}}' \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/mitigated_domains" \
| jq .
# jsonplaceholder.typicode.com
curl -s -X POST \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
-H "Content-Type: application/json" \
-d '{"metadata":{"name":"jsonplaceholder.typicode.com","namespace":"xF5XC_NAMESPACEx"},"spec":{"mitigated_domain":"jsonplaceholder.typicode.com"}}' \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/mitigated_domains" \
| jq .

200 回應會返回已建立的緩解網域物件。409 回應表示該網域已在緩解清單中——這是成功條件。

列出所有已緩解的網域,並確認數量與剛才提交的網域數量相符:

Terminal window
curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/mitigated_domains" \
| jq '{count: (.items | length)}'
檢查項目預期結果狀態
已緩解網域數量6(與 POST 數量相符)若數量相符則 PASS
步驟 3 的所有 POST 均返回 200409每個網域均已接受PASS

如果數量低於預期,請從步驟 3 重新執行遺失網域的 POST 命令。

重新執行完全相同的合併模擬以擷取**「後」的快照**。模擬腳本完全相同——只有 CSD 的緩解狀態發生了變化。來自已緩解網域的腳本載入現在會被 CSD JavaScript 封鎖(&lt;script&gt; 標籤的 src 被清空為空字串)。

具備瀏覽器自動化工具的 AI 助理可使用相同的第二階段 initScript(逐字複製自第二階段 — AI 自動化執行)以程式方式重新執行攻擊模擬。initScript 儲存原生 fetch 以避免 zone.js 錯誤——這不影響 CSD 緩解,因為 CSD 不攔截 fetch() 呼叫。

  1. 以 initScript 導覽 — 使用帶有 isolatedContextnew_page 以取得乾淨的瀏覽器內容(避免步驟 2 遺留的舊 initScript),然後導覽至 about:blank,再以第二階段 initScript 導覽至登入頁面
  2. 關閉歡迎橫幅 — 以 press_key 按下 Escape
  3. 等待完成 — 等待 10 秒讓所有非同步回呼完成
  4. 擷取證據 — 以 list_console_messages 檢查是否有 [CSD Demo] Simulation complete;以 list_network_requests 過濾 scriptfetch 類型,觀察 CDN 腳本載入不存在(CSD 清空了腳本 src),而對外洩網域的 fetch 呼叫仍正常完成

不具備瀏覽器自動化工具的操作人員可依照與第二階段 — 步驟 8:攻擊模擬相同的程序手動重新執行模擬:

  1. 導覽至 http://xF5XC_DOMAINNAMEx/#/login
  2. 在電子郵件和密碼欄位中輸入虛擬憑證(勿提交)
  3. 開啟 DevTools——按 F12 並切換至 Console 分頁
  4. 貼上並執行來自觸發偵測的合併偵測腳本
  5. 觀察主控台和網路輸出——已緩解網域的 CDN 腳本 onloadonerror 回呼不會觸發(CSD 將腳本 src 清空為空字串,完全阻止了網路請求)。向外洩網域(www.httpbin.org、jsonplaceholder.typicode.com)發出的 Fetch 呼叫仍會完成,返回 200/201——CSD 緩解封鎖的是腳本載入,而非 fetch/XHR 呼叫
檢查項目預期結果(緩解後)狀態
CDN 腳本載入已封鎖 — 腳本不出現在網路分頁(CSD 將 src 清空為空字串)PASS
CDN 腳本回呼已緩解網域的 onloadonerror 均未觸發PASS
外洩 fetch 至 www.httpbin.org200 — fetch 仍完成(CSD 不攔截 fetch)INFO
外洩 fetch 至 jsonplaceholder.typicode.com201 — fetch 仍完成(CSD 不攔截 fetch)INFO
主控台輸出[CSD Demo] Simulation completePASS

這是示範的核心成果——並排比較的證據,證明在相同頁面、使用相同腳本執行的相同攻擊,現在產生了截然不同的結果。

信號緩解前(步驟 2)緩解後(步驟 5)
CDN 腳本載入200 — 所有 4 個 CDN 腳本正常載入已封鎖 — 腳本不出現在網路分頁(CSD 將 src 清空為空字串)
CDN onload 回呼出現 [Supply Chain] Loaded from 訊息無回呼觸發(未發出網路請求)
外洩至 www.httpbin.org200 — 資料已外洩200 — fetch 仍完成(CSD 不攔截 fetch)
外洩至 jsonplaceholder.typicode.com201 — 資料已外洩201 — fetch 仍完成(CSD 不攔截 fetch)
CSD 已緩解網域 API0 個已緩解6 個已緩解

每隔 60 秒查詢 /detected_domains,最多查詢 10 次(10 分鐘)。查詢返回結果後或達到 10 分鐘上限後,請繼續進行比較表——這些檢查僅供參考,不阻擋第四階段。

查詢緩解後的已偵測網域:

Terminal window
curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/detected_domains" \
| jq '{total_domains: .domain_summary.totalDomains, domains: [.domains_list[]? | {domain: .domain, category: .category}]}'

查詢腳本的已緩解狀態:

Terminal window
NOW=$(date +%s)
START=$(( NOW - 86400 ))
curl -s -X POST \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
-H "Content-Type: application/json" \
-d "{\"startTime\": \"$START\", \"endTime\": \"$NOW\"}" \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/scripts" \
| jq '{total: (.scripts | length), scripts: [.scripts[]? | {script_name: .script_name, risk_level: .risk_level}]}'
檢查項目預期結果狀態
基準線乾淨(步驟 1)開始時 0 個已緩解網域PASS / FAIL
前——攻擊成功(步驟 2)腳本載入,外洩返回 200/201PASS / FAIL
緩解措施已套用(步驟 3)所有 6 個網域均透過 POST 接受(200 或 409)PASS / FAIL
緩解數量已確認(步驟 4)清單中有 6 個項目PASS / FAIL
後——腳本載入已封鎖(步驟 5)CDN 腳本不出現在網路分頁,fetch 呼叫仍完成PASS / FAIL
前後比較(步驟 6)步驟 2 與步驟 5 的證據有明顯差異PASS / FAIL

第三階段完成。 當您準備好移除所有部署物件時,請繼續進行第四階段 — 拆除