VYPR
Moderate severityOSV Advisory· Published Sep 25, 2020· Updated Sep 16, 2024

Command Injection

CVE-2020-7735

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.

PackageAffected versionsPatched versions
ng-packagrnpm
< 10.1.110.1.1

Affected products

2

Patches

1
bda0fff34433

fix: replace execFile with execFileSync to fix a potential malicious cmd injection

https://github.com/ng-packagr/ng-packagrAlan AgiusSep 25, 2020via ghsa
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

News mentions

0

No linked articles in our index yet.