Skip to content

fix(devtools): guard mutating RPCs to local clients - #9123

Merged
maiieul merged 4 commits into
QwikDev:mainfrom
Aejkatappaja:fix/devtools-rpc-local-guard
Oct 3, 2026
Merged

maiieul merged 4 commits into
QwikDev:mainfrom
Aejkatappaja:fix/devtools-rpc-local-guard

Conversation

@Aejkatappaja

@Aejkatappaja Aejkatappaja commented Oct 2, 2026 •

Copy link
Copy Markdown
Member

What is it?

  • Bug

Description

DevTools already had a loopback guard for the build-analysis rebuild, but it never worked. birpc awaits before it calls the RPC function, so by then the request context set around the websocket handler was already cleared and every caller looked remote. From localhost the "Build Report" button never showed up.

The package install and update RPCs had no guard at all. If the dev server was reachable from another machine, for example a phone or laptop on the same network with vite --host, that machine could add or update dependencies in your project from the Packages tab.

This PR has three commits:

  1. test(devtools): run test files vitest was skipping. The root vitest config only picks up *.unit.* and *.spec.*, so 8 devtools *.test.ts files never ran. They are renamed (31 more tests running, all green), the duplicate ssrPerfMiddleware suite is merged, and __snapshots__ is excluded from the include so the renamed .snap file isn't treated as a test.
  2. fix(devtools): keep the RPC caller context during async dispatch. The context is captured in the birpc resolver, which runs synchronously when the message arrives, and set again around the call. getBuildAnalysisStatus now reads it before its first await. The new tests go through the real RPC dispatch with a fake Vite websocket instead of mocking the context, since the mock is what hid this.
  3. fix(devtools): restrict package install and update to local clients. Same loopback check as build analysis, moved to plugin/src/rpc/security.ts so both features share it. QWIK_DEVTOOLS_ALLOW_REMOTE_PACKAGE_MANAGEMENT=1 opts back in for setups like Docker where the browser is never on loopback.

A client behind a reverse proxy on localhost still counts as local. That was already the case for build analysis and I left it alone.

Demo

Recorded against a Router SSR app with qwikDevtools(). First on localhost, where rebuild and install both work, then the same page opened through the LAN IP, where both are refused with the opt-in hint.

devtools-rpc-guard-demo.mp4

Checklist

  • My code follows the developer guidelines of this project
  • I performed a self-review of my own code
  • I added a changeset with pnpm change
  • I added new tests to cover the fix / functionality

The root vitest config only picks up *.unit.* and *.spec.*, so the devtools *.test.ts files never ran. Rename them, merge the duplicate ssrPerfMiddleware suite, and keep __snapshots__ out of the test include.
birpc awaits before invoking a function, so the request context set around the websocket handler was already cleared and every call looked remote. Build analysis therefore refused to rebuild even from localhost. Carry the context through the birpc resolver and read it before the first await.
Any client that could reach the dev server websocket, for example a LAN device when Vite runs with --host, could add or update project dependencies through DevTools. Apply the same loopback guard build analysis uses, with QWIK_DEVTOOLS_ALLOW_REMOTE_PACKAGE_MANAGEMENT=1 as an explicit opt-in.
@Aejkatappaja
Aejkatappaja requested a review from a team as a code owner October 2, 2026 21:49
@changeset-bot

changeset-bot Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: f4195a6

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 8 packages
Name Type
@qwik.dev/devtools Patch
create-qwik Patch
eslint-plugin-qwik Patch
@qwik.dev/mcp Patch
@qwik.dev/react Patch
@qwik.dev/router Patch
@qwik.dev/utils Patch
@qwik.dev/core Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

@qwik.dev/core

npm i https://pkg.pr.new/QwikDev/qwik/@qwik.dev/core@9123

@qwik.dev/router

npm i https://pkg.pr.new/QwikDev/qwik/@qwik.dev/router@9123

@qwik.dev/utils

npm i https://pkg.pr.new/QwikDev/qwik/@qwik.dev/utils@9123

eslint-plugin-qwik

npm i https://pkg.pr.new/QwikDev/qwik/eslint-plugin-qwik@9123

create-qwik

npm i https://pkg.pr.new/QwikDev/qwik/create-qwik@9123

@qwik.dev/optimizer

npm i https://pkg.pr.new/QwikDev/qwik/@qwik.dev/optimizer@9123

@qwik.dev/devtools

npm i https://pkg.pr.new/QwikDev/qwik/@qwik.dev/devtools@9123

@qwik.dev/mcp

npm i https://pkg.pr.new/QwikDev/qwik/@qwik.dev/mcp@9123

commit: f4195a6

@maiieul

maiieul commented Oct 3, 2026

Copy link
Copy Markdown
Member

LGTM

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