#23355: Gateway: fail closed on untrusted proxy headers
gateway
size: S
trusted-contributor
Cluster:
Security Enhancements and Fixes
## Summary
- add `gateway.rejectUntrustedProxyHeaders` config support
- enforce fail-closed websocket handshake rejection (`1008`) when `X-Forwarded-For`/`X-Real-IP` are present from an untrusted source and the policy is enabled
- compute default policy as enabled when `gateway.bind != loopback` or `gateway.auth.mode = trusted-proxy`
- keep existing behavior available via explicit override (`gateway.rejectUntrustedProxyHeaders: false`)
- add e2e coverage for explicit enable, non-loopback default enable, and explicit disable flows
## Testing
- pnpm test:e2e src/gateway/server.auth.e2e.test.ts
- pnpm test src/gateway/server-runtime-config.test.ts
- pnpm check
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
This PR introduces comprehensive security hardening for gateway connections and proxy header handling:
- Adds `gateway.rejectUntrustedProxyHeaders` configuration with secure defaults (enabled when `bind != loopback` or `auth.mode = trusted-proxy`)
- Enforces fail-closed WebSocket handshake rejection with `1008` status code when `X-Forwarded-For`/`X-Real-IP` headers are present from untrusted sources
- Hardens control-ui file serving with symlink escape prevention using `fs.realpathSync` and `isWithinDir` checks
- Requires TLS for all non-loopback gateway connections across platforms (Android, iOS, macOS)
- Adds security close tracking and alerting for repeated `4008` closes in the UI
- Implements CIDR subnet matching for trusted proxy IP validation
- Enhances webhook security with improved IP normalization and loopback detection
- Adds comprehensive test coverage including e2e tests for explicit enable/disable flows and platform-specific TLS enforcement
<h3>Confidence Score: 5/5</h3>
- Safe to merge - comprehensive security hardening with thorough test coverage and fail-safe defaults
- Extensive security improvements with fail-closed defaults, comprehensive cross-platform test coverage (e2e, unit, Android, iOS), backward compatibility via explicit override flags, and defense-in-depth approach across gateway, webhooks, and UI layers
- No files require special attention
<sub>Last reviewed commit: d5364db</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#23735: Gateway: add first-class wss validation and remote TLS guidance
by bmendonca3 · 2026-02-22
85.2%
#23425: Gateway: require trusted-proxy allowlist unless allowAll is explicit
by bmendonca3 · 2026-02-22
84.6%
#23361: Gateway: reject scope assertions without identity binding
by bmendonca3 · 2026-02-22
84.1%
#23364: Gateway: add risk-ack interlock for dangerous Control UI flags
by bmendonca3 · 2026-02-22
82.3%
#21120: Security/Gateway: guard dangerous HTTP /tools/invoke re-enables
by bmendonca3 · 2026-02-19
81.4%
#23714: Gateway: add websocket ingress limits for DoS hardening
by bmendonca3 · 2026-02-22
81.2%
#7654: feat(security): zero-trust localhost auth with DNS rebinding protec...
by joncode · 2026-02-03
80.6%
#17705: fix(gateway): allow trusted-proxy auth to bypass device-pairing gates
by dashed · 2026-02-16
80.6%
#21326: Security/UI: harden Control UI gatewayUrl URL overrides
by bmendonca3 · 2026-02-19
80.4%
#21964: Security: harden gateway and plugin trust boundaries
by Elormyevu · 2026-02-20
80.2%