You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix(devtools): require the dev auth token for server config and storage mounts - #1124
#1049 meant to strip private runtimeConfig from getServerConfig for callers without a token. A second getServerConfig in server-data.ts returned raw nuxt.options. It is spread last in server-rpc/index.ts, so it replaced the redacted one.
Fixing the shadowing alone is not enough. Secrets in the resolved options are not limited to runtimeConfig. They also sit under nitro.runtimeConfig, _layers[].config, module options and nitro.storage driver options. getStorageMounts returned the same driver options without a token.
This PR gates these payloads on the dev auth token instead of redacting them. v4 already authorizes every RPC call the same way.
useServerConfig passes ensureDevAuthToken(). It refetches when isDevAuthed changes, so dismissing the first prompt and authorizing later still loads the data.
While unauthorized, the overview shows an authorize button instead of an endless "Loading...".
authConfirmAction waited on until(devAuthToken.value). That is a plain value, so pasting a token into the dialog never resumed the pending call. This affected every token-gated action. It now watches the ref (separate commit), and the first-open prompt depends on it.
Evidence
The probe calls RPC methods over the HMR socket without an Origin header. The fixture app has a synthetic secret in runtimeConfig, in a module option and in a storage mount password.
Call
Before
After
getServerConfig()
secret at 7 paths
Invalid dev auth token
getServerConfig(), duplicate removed only
secret at nitro.runtimeConfig, _layers[0].config.*
-
getStorageMounts()
secret in mount options
Invalid dev auth token
getServerConfig(validToken)
-
full options
test/server-rpc-private-data.test.ts calls the combined RPC table that the socket dispatches to:
Before: 3 of 4 tests fail
After: 4 of 4 tests pass
Other checks:
pnpm test:unit: 18 passed
pnpm exec vue-tsc --noEmit: clean
pnpm build: 4 of 4 tasks
eslint on the changed files: clean
DevTools UI, opened in a fresh browser profile against a fixture app (nuxt dev, 1280x720):
State
Before
After
First open
welcome page, no prompt
welcome page behind the "Permissions required" dialog
Overview, unauthorized
full project data plus the "untrusted browser" tip
prompt dismissed: only a "Project data requires authorization" button
In the browser I also checked that pasting the token loads the overview, that a reload skips the prompt, and that the Storage tab lists its mounts.
Not verified: getServerDebugContext (no token required) with Nuxt debug enabled.
Merge Danger
Door: two-way
Blast Radius: devtools-kit consumers
The v3 DevTools UI asks to authorize the browser on first open. The token is kept in localStorage after that. Before this change, the overview and most views worked without authorization.
In @nuxt/devtools-kit, ServerFunctions.getServerConfig, getStorageMounts and getStorageKeys now take a token. Third-party clients that call getServerConfig() get an auth error. The docs example now uses getComponents().
Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.
📝 Walkthrough
Server RPC methods for Nuxt configuration and storage data now require dev-auth tokens. Client requests supply tokens, and configuration state watches authorization changes. The modules overview page displays an authorization prompt when configuration is unavailable and the browser is not authorized. Tests cover token validation and valid access to configuration and storage mounts. The documentation example now awaits getComponents().
Configuration and storage-mount requests require authorization, and entering a valid token allows the configuration request to proceed. No actionable merge-blocking risk remains after normal checks.
Pre-merge checks: 4 · 1
Failed checks: 1 warning
Check name
Status
Explanation
Resolution
Docstring Coverage
Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 6 files. (3 skipped: 3…
Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed checks: 4 passed
Check name
Status
Explanation
Title check
The title clearly and concisely describes the main change: requiring the dev auth token for server configuration and storage mounts.
Description check
The description directly explains the security issue, the token-gating changes, client behavior, tests, compatibility impact, and verification results.
Linked Issues check
Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check
Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage
Explanation
Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 6 files. (3 skipped: 3 unsupported.)
Fix all pre-merge checks with AI
✨ Finishing Touches: 💡 1
📝 Generate docstrings: 💡
Commit to this branch
Create a new PR
🧪 Generate unit tests (beta)
Commit to this branch
Create a new PR
Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Warning
Some tools did not complete. Review the errors below.
🔧 ESLint
If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.
ESLint install timed out. The project may have too many dependencies for the sandbox.
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
#1049 meant to strip private
runtimeConfigfromgetServerConfigfor callers without a token. A secondgetServerConfiginserver-data.tsreturned rawnuxt.options. It is spread last inserver-rpc/index.ts, so it replaced the redacted one.Fixing the shadowing alone is not enough. Secrets in the resolved options are not limited to
runtimeConfig. They also sit undernitro.runtimeConfig,_layers[].config, module options andnitro.storagedriver options.getStorageMountsreturned the same driver options without a token.This PR gates these payloads on the dev auth token instead of redacting them. v4 already authorizes every RPC call the same way.
Client:
useServerConfigpassesensureDevAuthToken(). It refetches whenisDevAuthedchanges, so dismissing the first prompt and authorizing later still loads the data.authConfirmActionwaited onuntil(devAuthToken.value). That is a plain value, so pasting a token into the dialog never resumed the pending call. This affected every token-gated action. It now watches the ref (separate commit), and the first-open prompt depends on it.Evidence
The probe calls RPC methods over the HMR socket without an
Originheader. The fixture app has a synthetic secret inruntimeConfig, in a module option and in a storage mount password.getServerConfig()Invalid dev auth tokengetServerConfig(), duplicate removed onlynitro.runtimeConfig,_layers[0].config.*getStorageMounts()Invalid dev auth tokengetServerConfig(validToken)test/server-rpc-private-data.test.tscalls the combined RPC table that the socket dispatches to:Other checks:
pnpm test:unit: 18 passedpnpm exec vue-tsc --noEmit: cleanpnpm build: 4 of 4 tasksDevTools UI, opened in a fresh browser profile against a fixture app (
nuxt dev, 1280x720):In the browser I also checked that pasting the token loads the overview, that a reload skips the prompt, and that the Storage tab lists its mounts.
Not verified:
getServerDebugContext(no token required) with Nuxtdebugenabled.Merge Danger
Door: two-way
Blast Radius: devtools-kit consumers
@nuxt/devtools-kit,ServerFunctions.getServerConfig,getStorageMountsandgetStorageKeysnow take a token. Third-party clients that callgetServerConfig()get an auth error. The docs example now usesgetComponents().vite:serverCreatedhook #1123 editsserver-data.tsin a separate hunk.This PR was created with the help of an AI agent.