Skip to content

fix(remote-access): same-origin PTY WS upgrade + trusted-proxy-gated X-Forwarded-* trust#318

Merged
luokerenx4 merged 1 commit into
masterfrom
feat/remote-access-origin
Jun 11, 2026
Merged

fix(remote-access): same-origin PTY WS upgrade + trusted-proxy-gated X-Forwarded-* trust#318
luokerenx4 merged 1 commit into
masterfrom
feat/remote-access-origin

Conversation

@luokerenx4

Copy link
Copy Markdown
Contributor

Summary

  • Fixes the community-reported Tailscale/LAN self-hosting breakage (upgrade.origin_rejected): the PTY WebSocket origin gate was a static localhost-only allowlist; now it accepts same-origin upgrades (Origin host == Host header), mirroring the HTTP middleware's CSRF rule. Any direct bind — LAN IP, Tailscale IP, domain — works with zero config; cross-origin still 403s.
  • X-Forwarded-Proto / X-Forwarded-For are now only honored from a configured trusted proxy (OPENALICE_TRUSTED_PROXIES). Previously trusted unconditionally, contradicting the in-code comment and playbook 03 — any client could coerce a Secure cookie over plain HTTP and break login.
  • New README "Remote access" section: Tailscale/VPN/LAN direct (recommended), reverse-proxy recipe (nginx header block; Caddy works out of the box), public-internet caveats, cross-origin env vars (WEB_TERMINAL_ALLOWED_ORIGINS, OPENALICE_CSRF_TRUSTED_ORIGINS).
  • Playbook 07 updated to the new origin contract; new unit specs for both behaviors.

Test plan

  • npx tsc --noEmit clean
  • pnpm test passes (113 files / 1820 tests, incl. new workspaces-ws.spec.ts + routes/auth.spec.ts)
  • End-to-end on a real non-loopback path (same code path as Tailscale): bound 0.0.0.0, browser via LAN IP 192.168.31.49:47331 → admin-token login → resumed a paused workspace session → WS upgrade accepted, received {"type":"attached",pid:…} from the live claude PTY
  • Negative control: forged Origin: http://evil.example.com upgrade → 403 + upgrade.origin_rejected log

Boundary touch

Auth boundary: WS origin gate semantics (same-origin acceptance — browser Origin is not forgeable from a foreign page, so this admits exactly pages Alice served itself) and forwarded-header trust (strictly narrowed, never widened).

🤖 Generated with Claude Code

…X-Forwarded-* trust

The PTY WebSocket origin gate was a static localhost-only allowlist, so any
non-localhost access (Tailscale IP, LAN IP, a domain) got 403
upgrade.origin_rejected on the workspace terminal — while the HTTP CSRF
check already did dynamic same-origin comparison. Community-reported against
the documented Docker/LAN self-hosting path.

- workspaces-ws: accept same-origin upgrades (Origin host == Host header),
  mirroring the HTTP middleware; static allowlist + WEB_TERMINAL_ALLOWED_ORIGINS
  remain for cross-origin topologies. Unit-specced.
- routes/auth: honor X-Forwarded-Proto / X-Forwarded-For only when the socket
  peer is a configured trusted proxy (previously trusted unconditionally,
  contradicting the code comment and playbook 03 — an attacker could coerce a
  Secure cookie over plain HTTP). Wired trustedProxies from WebPlugin.
- README: new "Remote access" section (Tailscale/LAN direct, reverse proxy
  recipe with nginx headers, public-internet caveats, cross-origin env vars).
- playbook 07 updated to the new origin contract.

Verified end-to-end: bound 0.0.0.0, logged in and attached a live workspace
PTY via LAN IP origin (same code path as Tailscale); cross-origin upgrade
still 403s.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
openalice-demo Ready Ready Preview, Comment Jun 11, 2026 8:09am

Request Review

@luokerenx4 luokerenx4 merged commit c0e93fa into master Jun 11, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant