- Home
- Client-Side Defense
- demo
- Phase 3 — Mitigate
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.
Check Mitigated Domains Count
Section titled “Check Mitigated Domains Count”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:
# 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.
Confirm Phase 2 Detections Are Present
Section titled “Confirm Phase 2 Detections Are Present”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}]}'Evidence
Section titled “Evidence”| Check | Expected | Status |
|---|---|---|
| Mitigated domain count | 0 (clean baseline) | PASS if 0, requires cleanup if > 0 |
| Detected domain count | > 0 (Phase 2 detections present) | PASS if > 0 |
| Exfil domains present | www.httpbin.org, jsonplaceholder.typicode.com | PASS if at least one appears |
Step 2: Run Attack — Before Mitigation
Section titled “Step 2: Run Attack — Before Mitigation”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-Automated Execution
Section titled “AI-Automated Execution”AI assistants with browser automation tools run the attack simulation programmatically using the same Phase 2 initScript (which saves native fetch):
- Navigate with initScript — first navigate to
about:blankto ensure a clean document context (avoids stale initScripts from prior navigations), thennavigate_pagetohttp://$F5XC_DOMAINNAME/#/loginwith the Phase 2 initScript (verbatim code in Phase 2 — AI-Automated Execution). This initScript saves nativesetInterval,clearInterval,fetch, andconsole.log— the nativefetchreference is correct here because no mitigations are active - Dismiss Welcome Banner —
press_keywithEscapeto 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 - Wait for completion — wait 10 seconds for all CDN script load/error callbacks and fetch promise resolutions to complete
- Capture evidence —
list_console_messagesto check for[CSD Demo] Simulation completeand CDN load results;list_network_requestsfiltered toscriptandfetchtypes to verify HTTP status codes (200/201for success)
Manual Execution
Section titled “Manual Execution”Operators without browser automation tools run the simulation manually using the same procedure as Phase 2 — Step 8: Attack Simulation:
- Navigate to
http://xF5XC_DOMAINNAMEx/#/login - Enter dummy credentials in the Email and Password fields (do not submit)
- Open DevTools — press F12 and switch to the Console tab
- Paste and run the Combined Detection Script from Trigger Detection
- Observe console output — all CDN scripts should load and exfil calls should succeed with
200/201responses
Evidence — Before Mitigation
Section titled “Evidence — Before Mitigation”| Check | Expected (Before Mitigation) | Status |
|---|---|---|
| CDN scripts injected | All 4 script tags load — [Supply Chain] Loaded from messages appear, network tab shows 200 | PASS |
Exfil fetch to www.httpbin.org | Network tab shows 200 — data sent | PASS |
| Exfil fetch to jsonplaceholder.typicode.com | Network tab shows 201 — data sent | PASS |
| Console output | [CSD Demo] Simulation complete | PASS |
Step 3: Apply Mitigations
Section titled “Step 3: Apply Mitigations”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):
| Domain | Role |
|---|---|
cdn.jsdelivr.net | CDN script injection |
esm.sh | CDN script injection |
unpkg.com | CDN script injection |
ga.jspm.io | CDN script injection |
www.httpbin.org | Data exfiltration endpoint |
jsonplaceholder.typicode.com | Data exfiltration endpoint |
Mitigate a domain (run once per domain):
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:
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.comcurl -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.iocurl -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.comcurl -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.
Step 4: Verify Mitigations Applied
Section titled “Step 4: Verify Mitigations Applied”List all mitigated domains and confirm the count matches the number of domains just submitted:
curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/mitigated_domains" \ | jq '{count: (.items | length)}'Evidence
Section titled “Evidence”| Check | Expected | Status |
|---|---|---|
| Mitigated domain count | 6 (matches POST count) | PASS if count matches |
All Step 3 POSTs returned 200 or 409 | Each domain accepted | PASS |
If the count is lower than expected, re-run the POST command for the missing domain from Step 3.
Step 5: Run Attack — After Mitigation
Section titled “Step 5: Run Attack — After Mitigation”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 <script> tag src is cleared to an empty string).
AI-Automated Execution
Section titled “AI-Automated Execution”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.
- Navigate with initScript — use
new_pagewithisolatedContextfor a clean browser context (avoids stale initScripts from Step 2), then navigate toabout:blank, then to the login page with the Phase 2 initScript - Dismiss Welcome Banner —
press_keywithEscape - Wait for completion — wait 10 seconds for all async callbacks
- Capture evidence —
list_console_messagesto check for[CSD Demo] Simulation complete;list_network_requestsfiltered toscriptandfetchtypes to observe that CDN script loads are absent (CSD cleared the script src) while fetch calls to exfil domains still complete normally
Manual Execution
Section titled “Manual Execution”Operators without browser automation tools re-run the simulation manually using the same procedure as Phase 2 — Step 8: Attack Simulation:
- Navigate to
http://xF5XC_DOMAINNAMEx/#/login - Enter dummy credentials in the Email and Password fields (do not submit)
- Open DevTools — press F12 and switch to the Console tab
- Paste and run the Combined Detection Script from Trigger Detection
- Observe console and network output — CDN script
onloadandonerrorcallbacks do not fire for mitigated domains (CSD cleared the scriptsrcto an empty string, preventing the network request entirely). Fetch calls to exfil domains (www.httpbin.org, jsonplaceholder.typicode.com) still complete with200/201— CSD mitigation blocks script loading, not fetch/XHR calls
Evidence — After Mitigation
Section titled “Evidence — After Mitigation”| Check | Expected (After Mitigation) | Status |
|---|---|---|
| CDN script loads | Blocked — scripts do not appear in network tab (CSD cleared src to empty string) | PASS |
| CDN script callbacks | Neither onload nor onerror fires for mitigated domains | PASS |
Exfil fetch to www.httpbin.org | 200 — fetch still completes (CSD does not intercept fetch) | INFO |
| Exfil fetch to jsonplaceholder.typicode.com | 201 — fetch still completes (CSD does not intercept fetch) | INFO |
| Console output | [CSD Demo] Simulation complete | PASS |
Step 6: Before vs After Comparison
Section titled “Step 6: Before vs After Comparison”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.
Comparison Table
Section titled “Comparison Table”| Signal | Before Mitigation (Step 2) | After Mitigation (Step 5) |
|---|---|---|
| CDN script loads | 200 — all 4 CDN scripts load normally | Blocked — scripts absent from network tab (CSD cleared src to empty string) |
CDN onload callbacks | [Supply Chain] Loaded from messages appear | No callbacks fire (no network request was made) |
Exfil to www.httpbin.org | 200 — data exfiltrated | 200 — fetch still completes (CSD does not intercept fetch) |
| Exfil to jsonplaceholder.typicode.com | 201 — data exfiltrated | 201 — fetch still completes (CSD does not intercept fetch) |
| CSD mitigated domains API | 0 mitigated | 6 mitigated |
Verify Mitigation in Backend Data
Section titled “Verify Mitigation in Backend Data”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:
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:
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}]}'Phase 3 Evidence Summary
Section titled “Phase 3 Evidence Summary”| Check | Expected | Status |
|---|---|---|
| Baseline clean (Step 1) | 0 mitigated domains at start | PASS / FAIL |
| Before — attack succeeds (Step 2) | Scripts load, exfil returns 200/201 | PASS / FAIL |
| Mitigations applied (Step 3) | All 6 domains accepted via POST (200 or 409) | PASS / FAIL |
| Mitigated count confirmed (Step 4) | 6 items in list | PASS / FAIL |
| After — script loads blocked (Step 5) | CDN scripts absent from network tab, fetch calls still complete | PASS / FAIL |
| Before vs After comparison (Step 6) | Clear difference between Step 2 and Step 5 evidence | PASS / FAIL |
Phase 3 complete. Proceed to Phase 4 — Teardown when you are ready to remove all deployment objects.