CVE-2018-3786
Description
Command injection in egg-scripts <2.8.1 allows arbitrary shell command execution via a maliciously crafted command line argument.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Command injection in egg-scripts <2.8.1 allows arbitrary shell command execution via a maliciously crafted command line argument.
Vulnerability
A command injection vulnerability exists in egg-scripts versions prior to 2.8.1. The start command passes user-supplied arguments (e.g., --stderr) to the shell by using child_process.exec() instead of child_process.execFile(), allowing shell metacharacters to be interpreted[1][2][3][4].
Exploitation
An attacker who can control the command line arguments passed to egg-scripts start can inject arbitrary shell commands. For example, appending a semicolon after a legitimate argument like --stderr enables execution of additional commands[2]. The attacker does not require authentication if they can directly invoke the start command with crafted arguments.
Impact
Successful exploitation results in arbitrary shell command execution with the privileges of the egg-scripts process. This can lead to complete compromise of the affected system, including data theft, installation of malware, or further lateral movement[1][4].
Mitigation
The vulnerability is fixed in egg-scripts version 2.8.1, released on August 19, 2018[3]. The fix replaces exec() with execFile() to avoid shell interpretation of arguments[2]. Users should upgrade to 2.8.1 or later. No workaround is available for earlier versions.
AI Insight generated on May 22, 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 |
|---|---|---|
egg-scriptsnpm | < 2.8.1 | 2.8.1 |
Affected products
2- Range: 2.8.1
Patches
1b98fd03d1e3afix: use execFile instead of exec for security reason (#26)
5 files changed · +38 −8
appveyor.yml+1 −1 modified@@ -2,7 +2,7 @@ environment: matrix: - nodejs_version: '6' - nodejs_version: '8' - - nodejs_version: '9' + - nodejs_version: '10' install: - ps: Install-Product node $env:nodejs_version
lib/cmd/start.js+7 −4 modified@@ -4,7 +4,7 @@ const path = require('path'); const Command = require('../command'); const debug = require('debug')('egg-script:start'); -const { exec } = require('mz/child_process'); +const { execFile } = require('mz/child_process'); const fs = require('mz/fs'); const homedir = require('node-homedir'); const mkdirp = require('mz-modules/mkdirp'); @@ -232,12 +232,15 @@ class StartCommand extends Command { if (hasError) { try { - const [ stdout ] = yield exec('tail -n 100 ' + stderr); + const args = [ '-n', '100', stderr ]; + this.logger.error('tail %s', args.join(' ')); + const [ stdout ] = yield execFile('tail', args); this.logger.error('Got error when startup: '); this.logger.error(stdout); - } catch (_) { - // nothing + } catch (err) { + this.logger.error('ignore tail error: %s', err); } + isSuccess = ignoreStdErr; this.logger.error('Start got error, see %s', stderr); this.logger.error('Or use `--ignore-stderr` to ignore stderr at startup.');
package.json+1 −1 modified@@ -50,7 +50,7 @@ "bin" ], "ci": { - "version": "6, 8, 9" + "version": "6, 8, 10" }, "bug": { "url": "https://github.com/eggjs/egg/issues"
test/start.test.js+28 −1 modified@@ -307,6 +307,7 @@ describe('test/start.test.js', () => { before(function* () { yield utils.cleanup(fixturePath); yield rimraf(logDir); + yield rimraf(path.join(fixturePath, 'start-fail')); yield mkdirp(logDir); }); @@ -315,6 +316,7 @@ describe('test/start.test.js', () => { yield utils.cleanup(fixturePath); yield rimraf(path.join(fixturePath, 'stdout.log')); yield rimraf(path.join(fixturePath, 'stderr.log')); + yield rimraf(path.join(fixturePath, 'start-fail')); }); it('should start', function* () { @@ -332,6 +334,30 @@ describe('test/start.test.js', () => { content = yield fs.readFile(stderr, 'utf-8'); assert(content === ''); }); + + it('should start with insecurity --stderr argument', function* () { + const cwd = path.join(__dirname, 'fixtures/status'); + mm(process.env, 'ERROR', 'error message'); + + const stdout = path.join(fixturePath, 'start-fail/stdout.log'); + const stderr = path.join(fixturePath, 'start-fail/stderr.log'); + const malicious = path.join(fixturePath, 'start-fail/malicious'); + app = coffee.fork(eggBin, [ + 'start', '--workers=1', '--daemon', `--stdout=${stdout}`, + `--stderr=${stderr}; touch ${malicious}`, + cwd, + ]); + // app.debug(); + + yield sleep(waitTime); + + const content = yield fs.readFile(stdout, 'utf-8'); + assert(!content.match(/custom-framework started on http:\/\/127\.0\.0\.1:7001/)); + let exists = yield fs.exists(stderr); + assert(!exists); + exists = yield fs.exists(malicious); + assert(!exists); + }); }); describe('read cluster config', () => { @@ -520,10 +546,11 @@ describe('test/start.test.js', () => { if (isWin) stderr = stderr.replace(/\\/g, '\\\\'); const app = coffee.fork(eggBin, [ 'start', '--daemon', '--workers=1' ], { cwd }); - // app.debug() + // app.debug(); // TODO: find a windows replacement for tail command if (!isWin) app.expect('stderr', /nodejs.Error: error message/); yield app.expect('stderr', new RegExp(`Start got error, see ${stderr}`)) + .expect('stderr', /Got error when startup/) .expect('code', 1) .end(); });
.travis.yml+1 −1 modified@@ -3,7 +3,7 @@ language: node_js node_js: - '6' - '8' - - '9' + - '10' install: - npm i npminstall && npminstall script:
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
7- github.com/advisories/GHSA-c9j3-wqph-5xx9ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2018-3786ghsaADVISORY
- github.com/eggjs/egg-scripts/blob/2.8.1/History.mdghsax_refsource_CONFIRMWEB
- github.com/eggjs/egg-scripts/commit/b98fd03d1e3aaed68004b881f0b3d42fe47341ddghsaWEB
- github.com/eggjs/egg-scripts/pull/26ghsax_refsource_CONFIRMWEB
- hackerone.com/reports/388936ghsax_refsource_MISCWEB
- www.npmjs.com/advisories/694ghsaWEB
News mentions
0No linked articles in our index yet.