Skip to content

feat(core): allow configuring extra allowed origins for the DevTools WS transport#471

Merged
antfu merged 1 commit into
vitejs:mainfrom
dvcolomban:feat/ws-allowed-origins
Jul 24, 2026
Merged

feat(core): allow configuring extra allowed origins for the DevTools WS transport#471
antfu merged 1 commit into
vitejs:mainfrom
dvcolomban:feat/ws-allowed-origins

Conversation

@dvcolomban

Copy link
Copy Markdown
Contributor

Summary

The WS transport's origin check (isAllowedOrigin in devframe's attachWsRpcTransport) only recognizes literal loopback hostname patterns (localhost, 127.0.0.1, ::1, *.localhost) — it's a plain string match against the Origin header, not a DNS/hosts-file resolution. A custom dev hostname that resolves to loopback via /etc/hosts (a common pattern for running several HTTPS dev servers locally, each with its own hostname/cert) is invisible to that check, so every real browser connection gets rejected with a 403 before the WS handshake completes — even though the connection is genuinely local.

attachWsRpcTransport already accepts an allowedOrigins option for exactly this case, but @vitejs/devtools's own createWsServer never passes it through, and DevToolsConfig has no field for it.

This PR:

  • Adds DevToolsConfig.allowedOrigins?: string[]
  • Threads it through to attachWsRpcTransport({ ..., allowedOrigins }) in packages/core/src/node/ws.ts

Read through a narrow local cast rather than context.viteConfig.devtools?.config?.allowedOrigins directly, since Vite's published types bundle a frozen snapshot of DevToolsConfig and won't see a brand-new field until re-vendored — the same gap vite-augment.ts already works around for Plugin.devtools.

Test plan

Reproduced against a local embedded (route-bound) DevTools instance behind a custom /etc/hosts-aliased HTTPS hostname:

  • Before this change: every real browser connection to /__devtools/__ws got 403 Forbidden immediately (confirmed via a raw https.request upgrade probe with the browser's actual Origin header) — the client sat in status: "error" / isTrusted: false and eventually surfaced "Unauthorized" / a 60s RPC-trust timeout in the UI.
  • After this change, with the custom origin added via devtools: { allowedOrigins: [...] }: the WS handshake completes (101), the client reaches status: "connected" / isTrusted: true, and a custom dock renders live data.
  • tsc --noEmit on packages/core shows no new errors from these two files.
  • oxlint on the two touched files is clean.

…WS transport

The WS transport's origin check only recognizes literal loopback hostname
patterns (localhost, 127.0.0.1, etc) — it's a string match, not a DNS/hosts-file
resolution, so a custom dev hostname that resolves to loopback via /etc/hosts
(a common pattern for running multiple HTTPS dev servers locally) is rejected
with a 403 before the WS handshake completes, even though the connection is
genuinely local. Adds `DevToolsConfig.allowedOrigins` and threads it through to
`attachWsRpcTransport`, which already supports this via its own `allowedOrigins`
option — it just wasn't exposed.
@antfu
antfu merged commit f908793 into vitejs:main Jul 24, 2026
2 of 6 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.

2 participants