Command Injection
Description
ng-packagr before 10.1.1 allows command injection through the styleIncludePaths option, enabling arbitrary command execution.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
ng-packagr before 10.1.1 allows command injection through the styleIncludePaths option, enabling arbitrary command execution.
The vulnerability in ng-packagr arises from how the package handles the styleIncludePaths option when processing Less stylesheets. The tool constructs a shell command to invoke lessc by concatenating user-supplied include paths without proper sanitization, allowing an attacker to inject arbitrary commands via a crafted include path [1]. The fix in commit bda0fff replaced execSync with execFileSync, which passes arguments separately and prevents shell interpretation [3].
To exploit this, an attacker must be able to influence the build configuration, typically by modifying the ng-package.json file or the Angular workspace configuration. When the library is built, the malicious styleIncludePaths value is passed directly to the shell command, executing injected commands in the context of the build process. No authentication is required if the attacker already has write access to the project files.
Successful exploitation allows arbitrary command execution on the build server or developer machine, potentially leading to data theft, installation of backdoors, or further compromise of the build pipeline. The impact is high because build processes often have elevated privileges and access to sensitive data.
The issue is fixed in ng-packagr version 10.1.1 and later. Users are strongly advised to upgrade immediately [4]. No workarounds are available; updating the package is the only recommended mitigation.
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 |
|---|---|---|
ng-packagrnpm | < 10.1.1 | 10.1.1 |
Affected products
2- Range: next, v1.0.0, v1.0.0-alpha.0, …
Patches
1bda0fff34433fix: replace execFile with execFileSync to fix a potential malicious cmd injection
3 files changed · +7 −8
integration/samples/scss-paths/baz/baz component.less+0 −1 modified@@ -1,5 +1,4 @@ @import 'theme'; -@import 'less/test/less/debug/linenumbers'; .baz { .oom {
integration/samples/scss-paths/specs/metadata.ts+1 −1 modified@@ -33,7 +33,7 @@ describe(`@sample/scss-paths`, () => { expect(lessStyles).to.contain(`color:red`); }); - it(`should resolve the styles from the Less 'node_module' file ~`, () => { + xit(`should resolve the styles from the Less 'node_module' file ~`, () => { const lessStyles = METADATA['metadata']['BazComponent']['decorators'][0]['arguments'][0]['styles'][1]; expect(lessStyles).to.contain(`tst3`); });
src/lib/styles/stylesheet-processor.ts+6 −6 modified@@ -1,6 +1,6 @@ import * as path from 'path'; import * as log from '../utils/log'; -import { execSync } from 'child_process'; +import { execFileSync } from 'child_process'; // CSS Tools import * as autoprefixer from 'autoprefixer'; @@ -50,7 +50,7 @@ export class StylesheetProcessor { }); // Log warnings from postcss - result.warnings().forEach((msg) => log.warn(msg.toString())); + result.warnings().forEach(msg => log.warn(msg.toString())); return result.css; } @@ -75,12 +75,12 @@ export class StylesheetProcessor { case '.less': // this is the only way I found to make LESS sync - let cmd = `node "${require.resolve('less/bin/lessc')}" "${filePath}" --js`; + const args = [filePath, '--js']; if (this.styleIncludePaths.length) { - cmd += ` --include-path="${this.styleIncludePaths.join(':')}"`; + args.push(`--include-path=${this.styleIncludePaths.join(':')}`); } - return execSync(cmd).toString(); + return execFileSync(require.resolve('less/bin/lessc'), args).toString(); case '.styl': case '.stylus': @@ -126,7 +126,7 @@ export class StylesheetProcessor { const cssNanoPlugins = preset.plugins // replicate the `initializePlugin` behavior from https://github.com/cssnano/cssnano/blob/a566cc5/packages/cssnano/src/index.js#L8 .map(([creator, pluginConfig]) => creator(pluginConfig)) - .filter((plugin) => !asyncPlugins.includes(plugin.postcssPlugin)); + .filter(plugin => !asyncPlugins.includes(plugin.postcssPlugin)); postCssPlugins.push(...cssNanoPlugins);
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-qm28-7hqv-wg5jghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2020-7735ghsaADVISORY
- github.com/ng-packagr/ng-packagr/commit/bda0fff3443301f252930a73fdc8fb9502de596dghsax_refsource_MISCWEB
- snyk.io/vuln/SNYK-JS-NGPACKAGR-1012427ghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.