← Back to PRs

#22381: Security/Gateway: block cross-origin silent auto-pairing in auth mode none

by bmendonca3 open 2026-02-21 03:24 View on GitHub →
gateway size: S
## Summary - Problem: in gateway WS connect flow, `auth.mode=none` allowed local unpaired devices to be silently auto-approved based on loopback locality alone. - Why it matters: browser pages can initiate loopback WebSocket requests; untrusted cross-origin requests should not receive silent pairing approval. - What changed: gate silent auto-pairing on trusted browser origin (`checkBrowserOrigin`) in addition to existing local-direct checks. - What did NOT change (scope boundary): no changes to auth mode resolution, role/scope policy, or non-pairing gateway method authorization. ## Change Type (select all) - [x] Bug fix - [ ] Feature - [ ] Refactor - [ ] Docs - [x] Security hardening - [ ] Chore/infra ## Scope (select all touched areas) - [x] Gateway / orchestration - [ ] Skills / tool execution - [x] Auth / tokens - [ ] Memory / storage - [ ] Integrations - [ ] API / contracts - [ ] UI / DX - [ ] CI/CD / infra ## Linked Issue/PR - Closes # - Related #21618 ## User-visible / Behavior Changes - In `gateway.auth.mode=none`, cross-origin browser WS connects no longer get silent device auto-pair approval; they now receive normal `pairing required` flow. ## Security Impact (required) - New permissions/capabilities? (`No`) - Secrets/tokens handling changed? (`No`) - New/changed network calls? (`No`) - Command/tool execution surface changed? (`No`) - Data access scope changed? (`No`) - If any `Yes`, explain risk + mitigation: ## Repro + Verification ### Environment - OS: macOS - Runtime/container: Node 22, pnpm - Model/provider: N/A - Integration/channel (if any): Gateway WS - Relevant config (redacted): `gateway.auth.mode=none` ### Steps 1. Start gateway with `gateway.auth.mode=none`. 2. Open WS with non-loopback Origin (`https://evil.example`) and send `connect` with fresh device identity. 3. Observe handshake result. ### Expected - Cross-origin browser request should not silently auto-pair; handshake should require explicit pairing approval. ### Actual - After fix, handshake returns `pairing required` (regression test added). ## Evidence - [x] Failing test/log before + passing after - [ ] Trace/log snippets - [ ] Screenshot/recording - [ ] Perf numbers (if relevant) ## Human Verification (required) What you personally verified (not just CI), and how: - Verified scenarios: - Targeted e2e: `does not silently auto-approve cross-origin browser pairing in mode none` passes. - Existing mode-none loopback connect test remains passing. - Edge cases checked: - Silent pairing path still allowed for trusted/local origin behavior. - What you did **not** verify: - Full matrix of every browser client ID + origin combination beyond targeted e2e coverage. ## Compatibility / Migration - Backward compatible? (`Yes`) - Config/env changes? (`No`) - Migration needed? (`No`) - If yes, exact upgrade steps: ## Failure Recovery (if this breaks) - How to disable/revert this change quickly: - Revert commit `889525b8e`. - Files/config to restore: - `src/gateway/server/ws-connection/message-handler.ts` - `src/gateway/server.auth.e2e.test.ts` - Known bad symptoms reviewers should watch for: - Unexpected pairing prompts for legitimate local-browser flows. ## Risks and Mitigations - Risk: - Overly strict origin trust could reduce convenience for some local browser workflows. - Mitigation: - Scope limited to silent auto-approval path; non-silent pairing fallback remains available. <!-- greptile_comment --> <h3>Greptile Summary</h3> Prevented cross-origin browser pages from silently auto-pairing in `gateway.auth.mode=none` by gating silent approval on trusted browser origin check. The fix adds `browserOriginTrustedForLocal` check to the silent pairing condition while preserving loopback auto-pairing for non-browser local clients (which don't send Origin headers). Test coverage includes regression test for cross-origin rejection and verification that legitimate loopback flows continue working. <h3>Confidence Score: 5/5</h3> - This PR is safe to merge with minimal risk - The fix is narrowly scoped, addresses a clear security vulnerability, includes targeted regression tests, and preserves existing legitimate flows. The logic is sound: browsers send Origin headers which can be validated, while non-browser clients don't send them and are treated as trusted by default. - No files require special attention <sub>Last reviewed commit: 889525b</sub> <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs