- Home
- Client-Side Defense
- Trigger Detection
Trigger Detection
CSD validation requires real browser-side JavaScript activity. The canonical Node.js 22 runner uses Chrome DevTools Protocol (CDP), enables Page, Runtime, Network, and Log/console collection, and writes a sanitized receipt. Immediate browser success and eventual CSD telemetry are separate facts.
1. Start a dedicated Chrome debugging profile
Section titled “1. Start a dedicated Chrome debugging profile”open -na "Google Chrome" --args \ --remote-debugging-port=9222 \ --user-data-dir="$TMPDIR/csd-demo-chrome"The runner creates and disposes an isolated browser context/page. It does not close Chrome.
2. Inspect the canonical scenarios
Section titled “2. Inspect the canonical scenarios”node scripts/csd-traffic.mjs --listThe list comes from scripts/lib/csd-scenarios.mjs and reports exactly these stable names:
login-credential-skimmer, registration-harvester, payment-overlay-card-skimmer,
obfuscated-loader, multi-cdn-injection, tag-manager-hijack,
multi-channel-exfiltration, high-volume-domain-exfiltration, form-overlay,
keylogger-simulation, and maximum-detection.
3. Run browser scenarios
Section titled “3. Run browser scenarios”An execution requires exactly one selector form: repeat --scenario for one or more selected
scenarios, or use --all. No scenario runs implicitly.
mkdir -p .artifacts/csdnode scripts/csd-traffic.mjs \ --scenario login-credential-skimmer \ --cdp-endpoint http://127.0.0.1:9222 \ --timeout 30s \ --settle 10s \ --receipt .artifacts/csd/login-credential-skimmer.jsonA focused multi-scenario run repeats --scenario:
node scripts/csd-traffic.mjs \ --scenario login-credential-skimmer \ --scenario payment-overlay-card-skimmer \ --receipt .artifacts/csd/focused.jsonRun the composed coverage scenario after a focused run is healthy:
node scripts/csd-traffic.mjs \ --scenario maximum-detection \ --receipt .artifacts/csd/maximum-detection.jsonUse --all only when all 11 independent entries are required:
node scripts/csd-traffic.mjs \ --all \ --receipt .artifacts/csd/all-scenarios.json--timeout bounds execution and navigation. --settle is only a browser-event collection period;
it is not a product-detection delay. A custom target requires --target plus an exact repeatable
--allow-host; unsafe schemes, hosts, ports, redirects, and final origins fail closed.
For pipelines, --receipt - sends only JSON to stdout and human logs to stderr:
node scripts/csd-traffic.mjs \ --scenario maximum-detection \ --receipt - \ | jq '{schema_version, run_id, requested_scenarios, success, eventual_csd_evidence}'4. Inspect immediate evidence first
Section titled “4. Inspect immediate evidence first”For a file receipt, inspect the stable evidence groups without assuming a fixed platform latency:
jq '{ schema_version, run_id, started_at, ended_at, duration_ms, tool, requested_scenarios, target, allowlist, cdp_endpoint, scenarios: [.scenarios[] | { name, target, status, immediate_evidence, dom_cleanup, console, network, protected_document, instrumentation, cleanup, error, success, eventual_csd_evidence }], success, caveats, error, eventual_csd_evidence}' .artifacts/csd/maximum-detection.jsonRequire the exact authorized top-frame origin, protected-page readiness, __imp_apg__, required
scenario assertions, real Network terminal outcomes, sanitized Log/console evidence, and complete
DOM/target/context/listener cleanup. The high-volume scenario must show five script attempts plus
two POST attempts. Keylogger evidence contains aggregate event and periodic flush/POST counts only.
Overlay evidence includes geometry/removal, and payment-overlay evidence confirms masked display-only
content.
A requested receipt is written atomically even when execution or cleanup fails. The receipt preserves
the primary error in error and reports runner cleanup failures in cleanup.errors. Candidate
failures and timed-out outcomes stay visible and are never relabeled as successful loads.
Manual fallback
Section titled “Manual fallback”node scripts/csd-traffic.mjs \ --print-script maximum-detection \ > .artifacts/csd/maximum-detection.browser.jsOpen the documented route, review the generated file, and paste it into DevTools Console.
--print-script is the only manual payload source. Record visible Console and Network outcomes;
manual execution cannot supply the automated receipt or cleanup proof.
Explicit post-receipt API correlation
Section titled “Explicit post-receipt API correlation”The generator has no embedded API client and does not read platform credentials. Only after the
browser receipt passes, separately use read-only xcsh_api operations. Scope them to the receipt’s
start/end window, protected origin, and exact reviewed hosts from Network evidence. Label each
result OBSERVED, NOT_OBSERVED, PENDING, or ERROR, and keep it under the separate
eventual_csd_evidence concept. Pending, empty, or failed correlation does not change a successful
immediate-browser result.
| Evidence | What it establishes | What it does not establish |
|---|---|---|
| Receipt and sanitized Log/console markers | The canonical payload ran in the accepted document. | CSD classification or causation. |
| Network terminal outcomes | Which reviewed destinations were attempted and what the browser observed. | That every candidate loaded or appeared in CSD. |
| Original-field and aggregate key counts | Field access and event handling occurred without retaining values. | Captured credentials, key content, or guaranteed classification. |
| Overlay geometry/removal | The synthetic overlay existed and cleanup removed it. | A guaranteed standalone injected-form signal. |
__imp_apg__ and dip evidence | Instrumentation existed and, when observed, emitted browser traffic. | A specific eventual risk label. |
| Separate CSD API results | Records returned during the queried window. | Deterministic latency, complete coverage, or causal attribution. |
The Attack Script Library contains the exact 11-scenario behavior and outcome matrix.
Page Tamper HTTP-Header Experiment
Section titled “Page Tamper HTTP-Header Experiment”Official mechanism and evidence boundary
Section titled “Official mechanism and evidence boundary”F5 documents that Page Tamper takes snapshots of HTTP headers and can raise
ClientSideDefenseHttpHeaderModified and ClientSideDefenseHttpHeaderCompromised alerts. Collection spans
multiple browser sessions and sequential cycles, and the baseline moves as observations accumulate. See
About Client-Side Defense and
Configure Client-Side Defense.
Those official sources do not publish an exact list of monitored headers. The following entries are experiment candidates, not a supported-coverage statement. Feature-Policy, when present, is a distinct legacy response header and must not be treated as evidence for Permissions-Policy.
Use only these classifications for the dedicated endpoint experiment:
- COMPROMISED — an exact
ClientSideDefenseHttpHeaderCompromisedrecord matches the namespace, selected header,/csd-page-tamper/payment, and experiment window. - MODIFIED_ONLY — an exact
ClientSideDefenseHttpHeaderModifiedrecord matches the same fields, but no matching Compromised record arrives within the valid window. - NO_ALERT_WITHIN_WINDOW — the complete traffic and telemetry chain is valid, but neither exact alert arrives within the bounded window. This does not prove unsupported behavior.
- INVALID_TEST — the baseline, cohort, telemetry, correlation, recovery, cleanup, readiness, or no-drift evidence chain is incomplete.
Verified historical evidence boundary
Section titled “Verified historical evidence boundary”On 2026-09-23, a tenant ClientSideDefenseHttpHeaderModified alert identified
x-content-type-options, x-frame-options, and cache-control, reported modification=Added, and
included the exact protected path /. This proves response-header detection for that event only. It
does not prove the Compromised trigger and does not establish a complete supported-header list.
2026-09-24 invalid experiment
Section titled “2026-09-24 invalid experiment”The campaign from 2026-09-24T20:22:00.476Z through 2026-09-24T20:30:11.388Z produced
108 of 108 fresh browser sessions with HTTP 200, six simultaneous global response-header value
changes, an injected CSD script, and a CSD dip POST. Restoration completed at
2026-09-24T21:40:51Z; workstation and worker checks agreed on canonical headers, the load
balancer remained ready with a valid certificate, Terraform reported no changes, and no worker
resources remained.
That campaign is INVALID TEST for Compromised-trigger conclusions. The load balancer changed all sessions together, so it provided neither an unchanged baseline cohort nor a simultaneous comparison cohort. Alert review also began with current alerts rather than alert history. Later searches across active, inactive, unprocessed, silenced, and inhibited states returned no matching Modified or Compromised record, but that bounded negative observation cannot establish per-header behavior or unsupported coverage.
Dedicated endpoint hypothesis
Section titled “Dedicated endpoint hypothesis”The controlled hypothesis uses the same URL for both cohorts:
/csd-page-tamper/payment. Control browsers receive the canonical synthetic payment page with all 12
candidate headers. Alternating tampered browsers send X-CSD-Page-Tamper: <header-id> and receive
the identical page with exactly the selected header absent; ordinary requests remain unchanged.
Individual experiments do not mutate the F5 Distributed Cloud load balancer or origin pool.
Bootstrap first proves the baseline from workstation and worker browsers, including all 12 exact
headers, the five empty synthetic fields, CSD injection, and dip telemetry. Each header then runs in
a separate window with control reinforcement, alternating control/tampered pairs, exact current and
history alert correlation, and control-only recovery. X-Content-Type-Options is the canary: if it
does not reach COMPROMISED, recover and stop the suite for diagnosis. A result is not successful
until recovery, cleanup, application health, load-balancer readiness, and final Terraform no drift
also pass. This method remains an unproven hypothesis until live evidence satisfies those gates.
2026-09-25/26 live result
Section titled “2026-09-25/26 live result”The dedicated endpoint was deployed by the exact saved Terraform plan (5 add, 1 change, 1 destroy
for a task-definition replacement) with zero F5 Distributed Cloud mutations. Bootstrap run
dd91ea9b-3da3-4fc8-b24b-c32cdba2e863 ran from 2026-09-25T21:40:23.373Z to
2026-09-25T22:42:18.638Z. It returned alerts=[] and proved the endpoint and root healthy,
all 12 canonical candidate headers exact, all five synthetic payment fields empty, the CSD script
present, both ALB target groups healthy, load-balancer state VIRTUAL_HOST_READY, certificate
state CertificateValid, and Terraform no drift.
The valid X-Content-Type-Options canary run
69f30bd0-6dc2-4721-bb21-cae159032af2 ran from 2026-09-25T23:21:44.908Z to
2026-09-26T00:38:11.806Z. It completed 12 of 12 controls and 20 of 20 mixed pairs with
valid telemetry. Neither an exact Modified nor Compromised alert correlated; alerts=[], and the
only correct outcome is NO_ALERT_WITHIN_WINDOW. Post-run current alerts returned zero and alert
history returned an empty array.
Recovery completed with 10 control pairs, successful probes, readiness, cleanup, and Terraform
no drift. Because the canary did not reach COMPROMISED, the mandatory stop rule applied: the
remaining candidate headers were not run by design. This result validates the dedicated endpoint
and controlled test chain, but it does not validate the Compromised hypothesis, prove unsupported
behavior, or establish a monitored-header list.