CyberStrike has no proxy support anywhere today. Verified: no proxy handling in packages/hackbrowser/src, packages/cyberstrike/src/replay, or the config schema. The only transport control that exists is TLS verification — rejectUnauthorized, surfaced as the insecure_tls parameter (tool/http-replay.ts:273,615) — plus a NODE_TLS_REJECT_UNAUTHORIZED=0 scoped to the Chromium install step (tool/hackbrowser-launcher.ts:179).
The workflow this blocks: an operator wants everything CyberStrike sends to appear in their own intercepting proxy, so it can be inspected, diffed and hand-replayed alongside the automated run.
Scope — every sender, named
hackbrowser and http_replay are the two the title mentions, but they are not the only components that open outbound connections. All of them must resolve the same config; the ones that must NOT be proxied need to be explicit rather than accidental.
| Sender |
Transport |
Proxied? |
| hackbrowser crawler |
Chromium (Playwright) |
yes |
| hackbrowser → session ingest |
worker fetch to the local server |
never — bypass |
http_replay |
replay/backend-fetch.ts |
yes |
http_replay_raw |
replay/backend-socket.ts |
opt-in only (see rule 4) |
inject_probe |
own sender |
not directly — it is being moved onto the replay engine and will inherit from it |
webfetch, csrf_extract, credential recipe steps |
fetch |
yes |
| LLM / provider API calls |
provider SDKs |
opt-in, default off |
Config
Config-file only for v1 — no per-run or per-tool override.
Secrets use the {env:VAR} interpolation the config loader already supports (config/config.ts:1337). No credential is ever written to the config file in plaintext by us.
clientCertificates is a per-host list (Postman's model): resolution happens at send time by matching the request's host — and host:port when a port is given, so a target on a non-default port can carry its own certificate.
Behavior rules
- Absent or
enabled: false → today's behavior, byte for byte. This feature must have no effect on an unconfigured install.
- Loopback is always bypassed, whether or not it appears in
bypass. The crawler posts captured traffic to the local server; routing that through an external proxy would break ingest and duplicate every captured request into the proxy's history.
- Provider/LLM traffic is opt-in via
includeProviders, default false. When enabled, the proxy operator can see the API key in the request headers — the description text for this field must say so plainly.
- The raw-socket backend bypasses the proxy unless explicitly enabled. That backend exists to send byte-exact, deliberately malformed messages (smuggling / desync). An intercepting proxy re-frames HTTP/1.1 messages, which silently invalidates exactly those tests. If enabled, it must tunnel via
CONNECT and pass bytes through untouched.
insecure_tls on a single http_replay call still overrides for that call. Per-call beats config.
- Prefer
caPath over disabling verification. Trusting the intercepting proxy's CA keeps certificate validation on for the target; rejectUnauthorized: false should stay a last resort, not the documented way to use a proxy.
Implementation notes per sender
- Chromium: Playwright takes
proxy: { server, username, password, bypass } at launch or context level. The crawler runs in a subprocess and only receives serializable options, so the resolved proxy/TLS descriptor has to be added to WorkerOptions (hackbrowser-subprocess/worker-ipc.ts) the same way the model descriptor already is.
backend-fetch.ts: already constructs an init.tls object for rejectUnauthorized (replay/backend-fetch.ts:104) — the CA and proxy settings extend the same spot.
backend-socket.ts: raw net / tls connect (replay/backend-socket.ts:100-106). Needs a CONNECT handshake before the TLS upgrade when proxying is enabled, and the CA / client-certificate options belong on the tls.connect call.
- Bypass matching should be one shared helper, not reimplemented per backend — the crawler already has host-pattern matching for network scope (
packages/hackbrowser/src/scope.ts) and the same wildcard semantics should apply here.
Out of scope for this issue
- Per-run or per-tool proxy override (config only for now)
- PAC files and proxy auto-detection
- SOCKS support for the raw-socket backend
- Recording/exporting proxy traffic inside CyberStrike
To verify during implementation
- Whether Chromium picks up the OS proxy when Playwright is given no
proxy option — this determines what "no config → today's behavior" actually means on each platform.
fetch proxy semantics on the runtime the main process uses, specifically HTTPS via CONNECT, and whether the TLS ca option takes a path or a buffer.
- Playwright's per-context
clientCertificates support at the pinned version, and whether it accepts the same per-host shape proposed above.
CyberStrike has no proxy support anywhere today. Verified: no proxy handling in
packages/hackbrowser/src,packages/cyberstrike/src/replay, or the config schema. The only transport control that exists is TLS verification —rejectUnauthorized, surfaced as theinsecure_tlsparameter (tool/http-replay.ts:273,615) — plus aNODE_TLS_REJECT_UNAUTHORIZED=0scoped to the Chromium install step (tool/hackbrowser-launcher.ts:179).The workflow this blocks: an operator wants everything CyberStrike sends to appear in their own intercepting proxy, so it can be inspected, diffed and hand-replayed alongside the automated run.
Scope — every sender, named
hackbrowserandhttp_replayare the two the title mentions, but they are not the only components that open outbound connections. All of them must resolve the same config; the ones that must NOT be proxied need to be explicit rather than accidental.fetchto the local serverhttp_replayreplay/backend-fetch.tshttp_replay_rawreplay/backend-socket.tsinject_probewebfetch,csrf_extract, credential recipe stepsfetchConfig
Config-file only for v1 — no per-run or per-tool override.
{ "network": { "proxy": { "enabled": true, "url": "http://proxy.example.com:8080", "auth": { "username": "operator", "password": "{env:CS_PROXY_PASSWORD}" }, "bypass": ["localhost", "127.0.0.1", "::1", "*.internal.example.com"], "includeProviders": false }, "tls": { "caPath": "/path/to/intercepting-ca.pem", "rejectUnauthorized": true, "clientCertificates": [ { "host": "app.example.com", "certPath": "/path/to/client.crt", "keyPath": "/path/to/client.key", "passphrase": "{env:CS_CLIENT_CERT_PASSPHRASE}" }, { "host": "api.example.com:8443", "pfxPath": "/path/to/client.pfx", "passphrase": "{env:CS_CLIENT_CERT_PASSPHRASE}" } ] } } }Secrets use the
{env:VAR}interpolation the config loader already supports (config/config.ts:1337). No credential is ever written to the config file in plaintext by us.clientCertificatesis a per-host list (Postman's model): resolution happens at send time by matching the request's host — andhost:portwhen a port is given, so a target on a non-default port can carry its own certificate.Behavior rules
enabled: false→ today's behavior, byte for byte. This feature must have no effect on an unconfigured install.bypass. The crawler posts captured traffic to the local server; routing that through an external proxy would break ingest and duplicate every captured request into the proxy's history.includeProviders, defaultfalse. When enabled, the proxy operator can see the API key in the request headers — the description text for this field must say so plainly.CONNECTand pass bytes through untouched.insecure_tlson a singlehttp_replaycall still overrides for that call. Per-call beats config.caPathover disabling verification. Trusting the intercepting proxy's CA keeps certificate validation on for the target;rejectUnauthorized: falseshould stay a last resort, not the documented way to use a proxy.Implementation notes per sender
proxy: { server, username, password, bypass }at launch or context level. The crawler runs in a subprocess and only receives serializable options, so the resolved proxy/TLS descriptor has to be added toWorkerOptions(hackbrowser-subprocess/worker-ipc.ts) the same way the model descriptor already is.backend-fetch.ts: already constructs aninit.tlsobject forrejectUnauthorized(replay/backend-fetch.ts:104) — the CA and proxy settings extend the same spot.backend-socket.ts: rawnet/tlsconnect (replay/backend-socket.ts:100-106). Needs aCONNECThandshake before the TLS upgrade when proxying is enabled, and the CA / client-certificate options belong on thetls.connectcall.packages/hackbrowser/src/scope.ts) and the same wildcard semantics should apply here.Out of scope for this issue
To verify during implementation
proxyoption — this determines what "no config → today's behavior" actually means on each platform.fetchproxy semantics on the runtime the main process uses, specifically HTTPS viaCONNECT, and whether the TLScaoption takes a path or a buffer.clientCertificatessupport at the pinned version, and whether it accepts the same per-host shape proposed above.