Skip to content

Allow WebSocket origins behind Host-rewriting reverse proxies - #22

Merged
powerfooI merged 1 commit into
mainfrom
fix/websocket-origin-allowlist
Aug 20, 2026
Merged

Allow WebSocket origins behind Host-rewriting reverse proxies#22
powerfooI merged 1 commit into
mainfrom
fix/websocket-origin-allowlist

Conversation

@powerfooI

Copy link
Copy Markdown
Owner

Problem

The browser-origin boundary introduced in #18 (released in 0.4.0) accepts WebSocket upgrades only when the request Origin host matches the request host. Deployments behind reverse proxies that terminate TLS and forward to an internal address rewrite the Host header, so legitimate browsers are rejected with 403 and the UI sits at "Browser disconnected from bridge". This is a 0.4.0 regression for proxied deployments: HTTP works, the page loads, but the bridge WebSocket never connects.

Changes

  • New HERDR_GUI_ALLOWED_ORIGINS env var / --allowed-origins flag: a comma-separated list of extra browser origins allowed to open the WebSocket. Entries are full origins (scheme://host[:port]); entries without a scheme match both http and https on that host.
  • The same-host rule and all other rejection paths are unchanged. Forwarded headers (X-Forwarded-Host etc.) are deliberately not trusted, since browser-supplied requests can set them.
  • README documents the setting and recommends preserving the original Host header when possible.

Verification

  • bun run precommit (format, lint, typecheck, 560 tests) green, including new allowlist cases
  • Live check against a running bridge: with the allowlist configured, a WS upgrade with a rewritten Host and the allowlisted browser origin upgrades (101); an unlisted origin is still rejected (403)
  • Reproduced the failure first: rewritten Host + public origin → 403 forbidden websocket origin without the allowlist

The 0.4.0 browser-origin boundary rejects WebSocket upgrades whose
Origin host differs from the request host. Reverse proxies that
terminate TLS and forward to an internal address rewrite the Host
header, so browsers connecting through them were stuck at "Browser
disconnected from bridge".

Add HERDR_GUI_ALLOWED_ORIGINS / --allowed-origins: a comma-separated
list of extra browser origins allowed to open the WebSocket. The
same-host rule and all other rejections are unchanged, and forwarded
headers are deliberately not trusted.
@powerfooI
powerfooI merged commit 61b884a into main Aug 20, 2026
1 check passed
@powerfooI
powerfooI deleted the fix/websocket-origin-allowlist branch August 20, 2026 06:59
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