Skip to content

Phase 3 — Mitigate

Phase 3 creates a before/after proof of CSD mitigation. You re-run the attack with no mitigations to establish a baseline, apply mitigations, then re-run the same attack to prove CSD blocks the network calls. Phase 2 must be complete — all DET checks PASS — before proceeding.

Step 1: Confirm No Active Mitigations (Baseline)

Section titled “Step 1: Confirm No Active Mitigations (Baseline)”

Before capturing the “before” snapshot, verify the environment is clean — no mitigations should be active. This ensures the baseline attack runs without any CSD blocking.

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)}'

If the count is not 0, mitigations remain from a prior run. Delete each one before proceeding:

Terminal window
# Delete a mitigated domain (repeat for each domain name)
curl -s -X DELETE \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/mitigated_domains/<domain-name>" \
| jq .

Replace <domain-name> with the metadata.name used when the domain was mitigated (e.g., cdn.jsdelivr.net, esm.sh, unpkg.com, ga.jspm.io, httpbin.org, jsonplaceholder.typicode.com). If httpbin.org cleanup leaves a remaining item, also try deleting www.httpbin.org — some prior runs may have used that as the 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}]}'
CheckExpectedStatus
Mitigated domain count0 (clean baseline)PASS if 0, requires cleanup if > 0
Detected domain count> 0 (Phase 2 detections present)PASS if > 0
Exfil domains presentwww.httpbin.org, jsonplaceholder.typicode.comPASS if at least one appears

Re-run the combined simulation with no mitigations active to capture a fresh baseline. This is the “before” snapshot — proof that attacks succeed when CSD mitigation is not applied.

AI assistants with browser automation tools run the attack simulation programmatically using the same Phase 2 initScript (which saves native fetch):

  1. Navigate with initScript — first navigate to about:blank to ensure a clean document context (avoids stale initScripts from prior navigations), then navigate_page to http://$F5XC_DOMAINNAME/#/login with the Phase 2 initScript (verbatim code in Phase 2 — AI-Automated Execution). This initScript saves native setInterval, clearInterval, fetch, and console.log — the native fetch reference is correct here because no mitigations are active
  2. Dismiss Welcome Bannerpress_key with Escape to close the Welcome Banner. On subsequent visits the banner may not appear (cookies persisted). The cookie consent dialog is dismissed automatically by the Escape key
  3. Wait for completion — wait 10 seconds for all CDN script load/error callbacks and fetch promise resolutions to complete
  4. Capture evidencelist_console_messages to check for [CSD Demo] Simulation complete and CDN load results; list_network_requests filtered to script and fetch types to verify HTTP status codes (200/201 for success)

Operators without browser automation tools run the simulation manually using the same procedure as Phase 2 — Step 8: Attack Simulation:

  1. Navigate to http://xF5XC_DOMAINNAMEx/#/login
  2. Enter dummy credentials in the Email and Password fields (do not submit)
  3. Open DevTools — press F12 and switch to the Console tab
  4. Paste and run the Combined Detection Script from Trigger Detection
  5. Observe console output — all CDN scripts should load and exfil calls should succeed with 200/201 responses
CheckExpected (Before Mitigation)Status
CDN scripts injectedAll 4 script tags load — [Supply Chain] Loaded from messages appear, network tab shows 200PASS
Exfil fetch to www.httpbin.orgNetwork tab shows 200 — data sentPASS
Exfil fetch to jsonplaceholder.typicode.comNetwork tab shows 201 — data sentPASS
Console output[CSD Demo] Simulation completePASS

For each detected domain, POST to the mitigated domains endpoint. The primary targets from the Phase 2 simulation are the 4 CDN injection domains and any data exfiltration domains detected.

Primary mitigation targets (from the combined simulation script):

DomainRole
cdn.jsdelivr.netCDN script injection
esm.shCDN script injection
unpkg.comCDN script injection
ga.jspm.ioCDN script injection
www.httpbin.orgData exfiltration endpoint
jsonplaceholder.typicode.comData exfiltration endpoint

Mitigate a domain (run once per domain):

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 .

Repeat for each domain:

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 — use www.httpbin.org as mitigated_domain (see note below)
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 .

A 200 response returns the created mitigated domain object. A 409 response means the domain is already in the mitigated list — this is a success condition.

List all mitigated domains and confirm the count matches the number of domains just submitted:

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)}'
CheckExpectedStatus
Mitigated domain count6 (matches POST count)PASS if count matches
All Step 3 POSTs returned 200 or 409Each domain acceptedPASS

If the count is lower than expected, re-run the POST command for the missing domain from Step 3.

Re-run the exact same combined simulation to capture the “after” snapshot. The simulation script is identical — only CSD’s mitigation state has changed. Script loads from mitigated domains are now blocked by the CSD JavaScript (the &lt;script&gt; tag src is cleared to an empty string).

AI assistants with browser automation tools re-run the attack simulation programmatically using the same Phase 2 initScript (verbatim code in Phase 2 — AI-Automated Execution). The initScript saves native fetch to avoid zone.js errors — this does not affect CSD mitigation because CSD does not intercept fetch() calls.

  1. Navigate with initScript — use new_page with isolatedContext for a clean browser context (avoids stale initScripts from Step 2), then navigate to about:blank, then to the login page with the Phase 2 initScript
  2. Dismiss Welcome Bannerpress_key with Escape
  3. Wait for completion — wait 10 seconds for all async callbacks
  4. Capture evidencelist_console_messages to check for [CSD Demo] Simulation complete; list_network_requests filtered to script and fetch types to observe that CDN script loads are absent (CSD cleared the script src) while fetch calls to exfil domains still complete normally

Operators without browser automation tools re-run the simulation manually using the same procedure as Phase 2 — Step 8: Attack Simulation:

  1. Navigate to http://xF5XC_DOMAINNAMEx/#/login
  2. Enter dummy credentials in the Email and Password fields (do not submit)
  3. Open DevTools — press F12 and switch to the Console tab
  4. Paste and run the Combined Detection Script from Trigger Detection
  5. Observe console and network output — CDN script onload and onerror callbacks do not fire for mitigated domains (CSD cleared the script src to an empty string, preventing the network request entirely). Fetch calls to exfil domains (www.httpbin.org, jsonplaceholder.typicode.com) still complete with 200/201 — CSD mitigation blocks script loading, not fetch/XHR calls
CheckExpected (After Mitigation)Status
CDN script loadsBlocked — scripts do not appear in network tab (CSD cleared src to empty string)PASS
CDN script callbacksNeither onload nor onerror fires for mitigated domainsPASS
Exfil fetch to www.httpbin.org200 — fetch still completes (CSD does not intercept fetch)INFO
Exfil fetch to jsonplaceholder.typicode.com201 — fetch still completes (CSD does not intercept fetch)INFO
Console output[CSD Demo] Simulation completePASS

This is the demo payoff — side-by-side evidence proving that the same attack, on the same page, with the same script, now produces a completely different result.

SignalBefore Mitigation (Step 2)After Mitigation (Step 5)
CDN script loads200 — all 4 CDN scripts load normallyBlocked — scripts absent from network tab (CSD cleared src to empty string)
CDN onload callbacks[Supply Chain] Loaded from messages appearNo callbacks fire (no network request was made)
Exfil to www.httpbin.org200 — data exfiltrated200 — fetch still completes (CSD does not intercept fetch)
Exfil to jsonplaceholder.typicode.com201 — data exfiltrated201 — fetch still completes (CSD does not intercept fetch)
CSD mitigated domains API0 mitigated6 mitigated

Query /detected_domains every 60 seconds for up to 10 iterations (10 minutes). Proceed to the comparison table once the query returns, or after the 10-minute maximum — these checks are informational and do not gate Phase 4.

Check Detected Domains Post-Mitigation:

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}]}'

Check Scripts for Mitigated Status:

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}]}'
CheckExpectedStatus
Baseline clean (Step 1)0 mitigated domains at startPASS / FAIL
Before — attack succeeds (Step 2)Scripts load, exfil returns 200/201PASS / FAIL
Mitigations applied (Step 3)All 6 domains accepted via POST (200 or 409)PASS / FAIL
Mitigated count confirmed (Step 4)6 items in listPASS / FAIL
After — script loads blocked (Step 5)CDN scripts absent from network tab, fetch calls still completePASS / FAIL
Before vs After comparison (Step 6)Clear difference between Step 2 and Step 5 evidencePASS / FAIL

Phase 3 complete. Proceed to Phase 4 — Teardown when you are ready to remove all deployment objects.