CVE-2021-34078
Description
A crafted dependency name in package.json can trigger OS command injection in lifion-verify-deps through 1.1.0.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
A crafted dependency name in package.json can trigger OS command injection in lifion-verify-deps through 1.1.0.
Vulnerability
lifion-verify-deps through version 1.1.0 is vulnerable to OS command injection. The library reads dependency names from a project's package.json file and passes them unsanitized into shell commands used to query npm registry information (e.g., via getLatestVersions and getLatestTag functions). An attacker who can control a dependency name — for example, by submitting a malicious package.json to a CI pipeline, a developer running lifion-verify-deps locally, or through an automated dependency scanning tool — can inject arbitrary OS commands. This arises because the library lacks sufficient validation of npm package names before interpolating them into command strings [1][2][4].
Exploitation
Exploitation requires the attacker to supply or influence a dependency name in the package.json file that lifion-verify-deps processes. No authentication or special privileges are needed beyond the ability to modify the package.json file's dependencies or devDependencies fields. The crafted name (e.g., a string containing shell metacharacters such as backticks or $()) is passed to functions like getLatestVersions(name) or getLatestTag(name), which internally execute shell commands without sanitization [2][4]. This can be achieved by committing a malicious package.json to a repository, supplying it through a pull request, or planting it in a directory that another user will scan with the tool.
Impact
Successful exploitation results in OS command injection, enabling the attacker to execute arbitrary commands with the privileges of the user or process running lifion-verify-deps. This can lead to full information disclosure (e.g., exfiltration of environment variables, source code, or credentials), file write or modification, and potential remote code execution depending on the environment. The impact is heightened in CI/CD pipelines where the tool may have access to deployment secrets or production systems [4].
Mitigation
The fix was introduced in commit be1133d5b78e3caa0004fa60207013dca4e1bf38 [3], which adds validation of npm package names using the library's isValidNpmPackageName function and rejects names that do not conform to npm's URL-friendly character set. Users should update to a version that includes this commit (if released). As of the CVE publication date (2022-06-01), no official patched release beyond 1.1.0 has been published, and the package appears unmaintained. Users are advised to discontinue use of lifion-verify-deps or carefully vet any package.json files passed to the tool, as no workaround is available in the source [2][3]. The vulnerability is not listed in CISA's Known Exploited Vulnerabilities (KEV) catalog as of the last check.
AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
lifion-verify-depsnpm | < 1.2.0 | 1.2.0 |
Affected products
2- lifion/lifion-verify-dependenciesdescription
Patches
1be1133d5b78eAdd validation for npm module name
4 files changed · +33 −1
lib/index.js+10 −0 modified@@ -9,10 +9,19 @@ const path = require('path'); const semver = require('semver'); const { exec } = require('child_process'); const { promisify } = require('util'); +const validatePackageName = require('validate-npm-package-name'); const execAsync = promisify(exec); +function isValidNpmPackageName(name) { + const { errors } = validatePackageName(name); + if (errors) { + throw new Error(`NPM package name: "${name}" is invalid. ${errors}`); + } +} + async function getLatestVersions(name) { + isValidNpmPackageName(name); const { stdout } = await execAsync(`npm view ${name} versions --json`); try { return JSON.parse(stdout); @@ -22,6 +31,7 @@ async function getLatestVersions(name) { } async function getLatestTag(name) { + isValidNpmPackageName(name); try { const { stdout } = await execAsync(`npm view ${name} dist-tags --json`); const { latest } = JSON.parse(stdout);
lib/index.test.js+8 −0 modified@@ -345,6 +345,14 @@ describe('lib/index', () => { expect(logger.info).toHaveBeenNthCalledWith(6, `Upgraded dependencies:\n["1.0.0"]`); expect(logger.info).toHaveBeenNthCalledWith(7, `Upgraded development dependencies:\n["1.0.0"]`); }); + + test('throw error when npm module name is invalid', async () => { + mockExports.dependencies = { 'bad name Dependency': '1.2.3' }; + mockExecAsync.mockImplementationOnce(mock); + await expect(verifyDeps({ autoUpgrade: true, dir, logger })).rejects.toThrow( + 'NPM package name: "bad name Dependency" is invalid. name can only contain URL-friendly characters' + ); + }); }); module.exports = mockExports;
package.json+2 −1 modified@@ -48,7 +48,8 @@ "dependencies": { "chalk": "^3.0.0", "minimist": "^1.2.5", - "semver": "^7.3.4" + "semver": "^7.3.4", + "validate-npm-package-name": "^3.0.0" }, "devDependencies": { "auto-changelog": "^1.16.4",
package-lock.json+13 −0 modified@@ -1565,6 +1565,11 @@ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", "dev": true }, + "builtins": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", + "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=" + }, "cache-base": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", @@ -8779,6 +8784,14 @@ "spdx-expression-parse": "^3.0.0" } }, + "validate-npm-package-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", + "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=", + "requires": { + "builtins": "^1.0.3" + } + }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4- github.com/advisories/GHSA-rphm-c8gw-3r38ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2021-34078ghsaADVISORY
- advisory.checkmarx.net/advisory/CX-2021-4785ghsax_refsource_MISCWEB
- github.com/lifion/lifion-verify-deps/commit/be1133d5b78e3caa0004fa60207013dca4e1bf38ghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.