#23352: Gateway: enforce origin checks for browser-context WS clients
gateway
size: S
trusted-contributor
## Summary
- enforce browser origin validation for any websocket client that either sends an `Origin` header or declares a browser client mode (`ui`/`webchat`)
- keep the Control UI-specific remediation message while returning a generic `origin not allowed` error for other clients
- add unit coverage for the new origin-enforcement gate logic
- add auth e2e coverage for non-Control-UI browser-mode clients across `Origin` missing, `null`, mismatched, and matching-host cases
## Testing
- pnpm test src/gateway/origin-check.test.ts
- pnpm test:e2e src/gateway/server.auth.e2e.test.ts
- pnpm check
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
This PR enhances browser origin validation for WebSocket clients by introducing a new `shouldCheckBrowserOrigin` gate that enforces origin checks for any client that either sends an `Origin` header OR declares a browser client mode (`ui`/`webchat`). The implementation correctly separates the decision logic (when to check) from the validation logic (what to check), making the security boundary more explicit and testable.
**Key security improvements:**
- Extends origin validation beyond Control UI to all browser-context clients (any client with `mode: ui` or `mode: webchat`)
- Enforces checks for any WebSocket client that sends an `Origin` header, regardless of declared mode
- Maintains Control UI-specific error messaging while returning generic "origin not allowed" for other clients
- Adds comprehensive e2e test coverage for non-Control-UI browser clients across missing, null, mismatched, and matching origin cases
**Platform security hardening:**
- **Android**: Requires TLS for non-loopback gateway connections with clear status errors for manual plaintext attempts; excludes `openclaw/identity` from cloud backup and device transfer to prevent identity material leakage
- **iOS**: Refactors `shouldForceTLS` → `shouldRequireTLS` and adds `resolveManualUseTLS` wrapper for clearer TLS enforcement logic
- **Web UI**: Validates gateway socket URLs before connection attempts using the shared `getGatewaySocketUrlSecurityError` helper
The changes align well with the codebase's existing security patterns and maintain backward compatibility for legitimate use cases.
<h3>Confidence Score: 4/5</h3>
- This PR is safe to merge with one minor test coverage improvement recommended
- The implementation is well-designed with clear separation of concerns, comprehensive e2e test coverage, and consistent security hardening across platforms. The only gap is a missing unit test for `WEBCHAT` mode in `shouldCheckBrowserOrigin`, which is a minor issue since the e2e tests cover Control UI (which uses `WEBCHAT` mode) extensively. The security logic is sound and follows the repository's established patterns.
- No files require special attention - the implementation is solid across all modified files
<sub>Last reviewed commit: 3577aef</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#10930: fix: validate WebSocket Origin for all client types, not just brows...
by OneZeroEight-ai · 2026-02-07
86.7%
#23361: Gateway: reject scope assertions without identity binding
by bmendonca3 · 2026-02-22
80.2%
#23355: Gateway: fail closed on untrusted proxy headers
by bmendonca3 · 2026-02-22
79.0%
#22381: Security/Gateway: block cross-origin silent auto-pairing in auth mo...
by bmendonca3 · 2026-02-21
79.0%
#23465: Gateway: strengthen Control UI security headers
by bmendonca3 · 2026-02-22
78.8%
#9146: Fix: Allow null-origin WebSocket connections from loopback
by vishaltandale00 · 2026-02-04
78.4%
#21326: Security/UI: harden Control UI gatewayUrl URL overrides
by bmendonca3 · 2026-02-19
77.9%
#23735: Gateway: add first-class wss validation and remote TLS guidance
by bmendonca3 · 2026-02-22
77.8%
#23364: Gateway: add risk-ack interlock for dangerous Control UI flags
by bmendonca3 · 2026-02-22
77.7%
#21100: Security/Gateway: require explicit break-glass env for Control UI b...
by bmendonca3 · 2026-02-19
76.8%