Problem
The new plaintext ws:// security check blocks all CLI operations (TUI, doctor, etc.) for WSL2 users who have gateway.bind: "lan".
Why bind: "lan" is needed on WSL2
WSL2 runs in a NAT'd VM with its own IP (e.g. 172.18.x.x). To access the gateway from Windows (webchat, browser), the gateway must bind to the LAN interface. bind: "localhost" would only be accessible from within WSL2 itself — Windows browser cannot reach it (WSL2 localhost forwarding is unreliable for WebSocket connections in many setups).
What happens
- Gateway binds to LAN IP (e.g. 172.18.252.63:18789)
- CLI resolves gateway URL as ws://172.18.252.63:18789
isSecureWebSocketUrl() in src/gateway/net.ts rejects it — non-loopback + plaintext
- Every CLI command fails:
openclaw tui, openclaw doctor, etc.
Error message
Error: SECURITY ERROR: Gateway URL "ws://172.18.252.63:18789" uses plaintext ws://
to a non-loopback address. Both credentials and chat data would be exposed to
network interception.
Workaround
openclaw tui --url ws://localhost:18789 --token <gateway-token>
This works because localhost resolves to loopback, and the gateway is still listening on all interfaces via the LAN bind. But it requires manually passing the token every time.
Suggested fixes
-
Best: Add a gateway.clientUrl config field that overrides the resolved URL for local CLI connections, separate from bind. Users could set clientUrl: "ws://localhost:18789" while keeping bind: "lan".
-
Alternative: Detect WSL2 environment and treat the WSL2 NAT range (172.16.0.0/12) as "local-equivalent" for the security check, since traffic never leaves the host machine.
-
Alternative: Allow a config flag like gateway.allowPlaintextLan: true to explicitly opt out of the check for users who understand the tradeoff.
Impact
This affects all WSL2 users who need webchat/browser access from Windows. The current workaround is cumbersome, and users who don't find it will likely migrate the gateway to Windows — which is a net downgrade to their security posture (less isolation, no sandboxing).
Environment
- OpenClaw 2026.2.19 (commit 035832b)
- WSL2 Ubuntu 24.04 on Windows 11
- Gateway config:
bind: "lan", mode: "local", port: 18789
Problem
The new plaintext ws:// security check blocks all CLI operations (TUI, doctor, etc.) for WSL2 users who have
gateway.bind: "lan".Why
bind: "lan"is needed on WSL2WSL2 runs in a NAT'd VM with its own IP (e.g. 172.18.x.x). To access the gateway from Windows (webchat, browser), the gateway must bind to the LAN interface.
bind: "localhost"would only be accessible from within WSL2 itself — Windows browser cannot reach it (WSL2 localhost forwarding is unreliable for WebSocket connections in many setups).What happens
isSecureWebSocketUrl()insrc/gateway/net.tsrejects it — non-loopback + plaintextopenclaw tui,openclaw doctor, etc.Error message
Workaround
This works because localhost resolves to loopback, and the gateway is still listening on all interfaces via the LAN bind. But it requires manually passing the token every time.
Suggested fixes
Best: Add a
gateway.clientUrlconfig field that overrides the resolved URL for local CLI connections, separate frombind. Users could setclientUrl: "ws://localhost:18789"while keepingbind: "lan".Alternative: Detect WSL2 environment and treat the WSL2 NAT range (172.16.0.0/12) as "local-equivalent" for the security check, since traffic never leaves the host machine.
Alternative: Allow a config flag like
gateway.allowPlaintextLan: trueto explicitly opt out of the check for users who understand the tradeoff.Impact
This affects all WSL2 users who need webchat/browser access from Windows. The current workaround is cumbersome, and users who don't find it will likely migrate the gateway to Windows — which is a net downgrade to their security posture (less isolation, no sandboxing).
Environment
bind: "lan",mode: "local",port: 18789