Skip to content

fix(update): validate package names in updateAllPackages#1357

Open
asdaxzcwqsa wants to merge 1 commit into
VoltAgent:mainfrom
asdaxzcwqsa:fix/update-all-packages-validation
Open

fix(update): validate package names in updateAllPackages#1357
asdaxzcwqsa wants to merge 1 commit into
VoltAgent:mainfrom
asdaxzcwqsa:fix/update-all-packages-validation

Conversation

@asdaxzcwqsa

@asdaxzcwqsa asdaxzcwqsa commented Jun 24, 2026

Copy link
Copy Markdown

Summary

  • reuse the existing npm package-name validation logic via a shared helper
  • filter invalid package names out of updateAllPackages() before building shell commands
  • bail out early when no valid packages remain, avoiding an empty package-manager invocation

Problem

updateAllPackages() was interpolating package names from checkForUpdates() directly into execSync() commands, while updateSinglePackage() already validated names first. That left a command-injection gap between the two code paths.

Notes

This keeps the fix intentionally small and follows the validation pattern already used in updateSinglePackage().

Fixes #1205


Summary by cubic

Validate package names in updateAllPackages() to close a command-injection gap and avoid empty package-manager runs. Reuses a shared regex helper and returns early when no valid packages remain.

  • Bug Fixes
    • Add shared isValidPackageName helper and use it in updateAllPackages().
    • Filter invalid names before building shell commands; skip updates if none are valid.
    • Update updateSinglePackage() to use the shared helper for consistency.

Written for commit d5e39d7. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Bug Fixes
    • Improved package update validation to skip invalid package names.
    • When no valid packages are available for an update, the update flow now fails clearly instead of proceeding.
    • Single-package updates continue to reject invalid names with the same early-return behavior.

@changeset-bot

changeset-bot Bot commented Jun 24, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: d5e39d7

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

A shared npm package-name regex constant (NPM_PACKAGE_NAME_REGEX) and helper (isValidPackageName) are introduced. updateAllPackages now filters candidate packages through this helper and returns an early failure when none pass. updateSinglePackage is updated to call the shared helper instead of an inline regex.

Changes

Package-name validation centralization and updateAllPackages security fix

Layer / File(s) Summary
Shared validation constant and helper
packages/core/src/utils/update/index.ts
Adds NPM_PACKAGE_NAME_REGEX and isValidPackageName as module-level constants, replacing the previously inline-only regex in updateSinglePackage.
Apply validation in both update functions
packages/core/src/utils/update/index.ts
updateAllPackages filters the candidate package list through isValidPackageName and adds an early success: false return when no valid names remain. updateSinglePackage replaces its inline regex test with a call to the shared helper.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~5 minutes

Poem

🐇 A crafty name could sneak inside,
And make the shell do things it'd hide.
Now every name must pass the test,
A regex guard secures the rest.
No injected tricks get through — hooray!
The warren's safe another day. 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description has summary/problem/notes, but it misses several required template sections like checklist, behavior, and tests/docs. Add the missing template sections: PR checklist, current/new behavior, linked issue details, tests, docs, and changeset status.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: validating package names in updateAllPackages.
Linked Issues check ✅ Passed The change matches #1205 by reusing shared validation, filtering invalid names, and stopping early when none remain.
Out of Scope Changes check ✅ Passed The diff is scoped to the requested package-name validation fix in update logic with no unrelated changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/core/src/utils/update/index.ts`:
- Around line 346-350: The new `success: false` return from `updateAllPackages`
is being swallowed by the API layer, so clients still see success. Update
`packages/server-core/src/handlers/update.handlers.ts` in the `update` handler
to inspect the result returned by `await updateAllPackages()` and forward its
`success` and `message` instead of always responding with `success: true`. Keep
the behavior aligned with the `updateAllPackages` early return path for “No
valid packages available for updating” so the handler surfaces failures
correctly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 19e657ea-09cc-4468-9e12-55976ed4dc11

📥 Commits

Reviewing files that changed from the base of the PR and between 17732a3 and d5e39d7.

📒 Files selected for processing (1)
  • packages/core/src/utils/update/index.ts

Comment on lines +346 to +350
if (packagesToUpdate.length === 0) {
return {
success: false,
message: "No valid packages available for updating",
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

success: false early-return is currently masked by the API handler.

Line 346 introduces a new { success: false } path, but packages/server-core/src/handlers/update.handlers.ts always returns success: true after await updateAllPackages() without checking the returned result. This means clients will still get a success response when this branch is hit. Either propagate the returned success/message in the handler or make this path fail in a way the handler surfaces.

🧰 Tools
🪛 ast-grep (0.44.0)

[warning] Importing child_process exposes a command-execution surface; ensure any command/argument built from input is validated, and prefer execFile/spawn with an argument array over exec.
Context: import { execSync } from "node:child_process";
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(detect-child-process-typescript)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/src/utils/update/index.ts` around lines 346 - 350, The new
`success: false` return from `updateAllPackages` is being swallowed by the API
layer, so clients still see success. Update
`packages/server-core/src/handlers/update.handlers.ts` in the `update` handler
to inspect the result returned by `await updateAllPackages()` and forward its
`success` and `message` instead of always responding with `success: true`. Keep
the behavior aligned with the `updateAllPackages` early return path for “No
valid packages available for updating” so the handler surfaces failures
correctly.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 1 file

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/core/src/utils/update/index.ts">

<violation number="1" location="packages/core/src/utils/update/index.ts:35">
P1: Package name regex allows leading dashes, permitting argument injection</violation>

<violation number="2" location="packages/core/src/utils/update/index.ts:348">
P2: This new `success: false` early-return path may not be surfaced to clients if the upstream handler (`update.handlers.ts`) always returns `success: true` after calling `updateAllPackages()` without inspecting the result. Either the handler should propagate the returned `success`/`message`, or this function should fail in a way the handler already surfaces (e.g., throwing an error).</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

*/
type PackageManager = "npm" | "pnpm" | "yarn" | "bun";

const NPM_PACKAGE_NAME_REGEX =

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Package name regex allows leading dashes, permitting argument injection

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/core/src/utils/update/index.ts, line 35:

<comment>Package name regex allows leading dashes, permitting argument injection</comment>

<file context>
@@ -32,6 +32,12 @@ export type PackageUpdateInfo = {
  */
 type PackageManager = "npm" | "pnpm" | "yarn" | "bun";
 
+const NPM_PACKAGE_NAME_REGEX =
+  /^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/;
+
</file context>
Suggested change
const NPM_PACKAGE_NAME_REGEX =
const NPM_PACKAGE_NAME_REGEX =
/^(@[a-z0-9~][a-z0-9-._~]*\/)?[a-z0-9~][a-z0-9-._~]*$/;


if (packagesToUpdate.length === 0) {
return {
success: false,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This new success: false early-return path may not be surfaced to clients if the upstream handler (update.handlers.ts) always returns success: true after calling updateAllPackages() without inspecting the result. Either the handler should propagate the returned success/message, or this function should fail in a way the handler already surfaces (e.g., throwing an error).

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/core/src/utils/update/index.ts, line 348:

<comment>This new `success: false` early-return path may not be surfaced to clients if the upstream handler (`update.handlers.ts`) always returns `success: true` after calling `updateAllPackages()` without inspecting the result. Either the handler should propagate the returned `success`/`message`, or this function should fail in a way the handler already surfaces (e.g., throwing an error).</comment>

<file context>
@@ -334,8 +340,16 @@ export const updateAllPackages = async (
 
+    if (packagesToUpdate.length === 0) {
+      return {
+        success: false,
+        message: "No valid packages available for updating",
+      };
</file context>

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.

[BUG] updateAllPackages missing command injection protection present in updateSinglePackage

1 participant