CVE-2017-16042
Description
Growl before 1.10.2 passes unsanitized user input to exec(), allowing arbitrary command execution.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Growl before 1.10.2 passes unsanitized user input to `exec()`, allowing arbitrary command execution.
Vulnerability
Growl, a Node.js package for sending Growl notifications, before version 1.10.2 does not properly sanitize input before passing it to the exec() function from child_process. This allows an attacker to inject arbitrary shell commands through specially crafted notification messages, titles, or image paths [1]. The vulnerability is present in versions prior to the fix merged in commits such as d71177d, which replaced exec with spawn and removed unsafe quoting functions [2].
Exploitation
An attacker who can control the msg, title, or image parameters passed to the growl() function can inject shell metacharacters. For example, a message containing backticks or command substitution characters (e.g., ` malicious_command ) would be executed by the shell when exec is called. The fix eliminated the use of quote() and passed arguments via spawn`'s array interface, preventing shell injection [2]. No authentication is required beyond the ability to invoke the library with attacker-controlled input.
Impact
Successful exploitation leads to arbitrary command execution on the system running the vulnerable Node.js application. The attacker can execute shell commands with the privileges of the process that calls growl(), potentially leading to full system compromise depending on the application's permissions [1].
Mitigation
The vulnerability is fixed in version 1.10.2 (and subsequent releases) by replacing exec with spawn and removing unsafe string quoting [2]. Users should upgrade to version 1.10.2 or later. If upgrading is not immediately possible, avoid passing untrusted input to the growl() function [3].
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 |
|---|---|---|
growlnpm | < 1.10.0 | 1.10.0 |
Affected products
2- HackerOne/growl node modulev5Range: <1.10.2
Patches
1d71177d5331cFix to resolve the command injection vulnerability. (#62)
3 files changed · +31 −27
History.md+5 −0 modified@@ -1,4 +1,9 @@ +1.9.3 / 2016-09-05 +================== + + * fixed command injection vulnerability + 1.7.0 / 2012-12-30 ==================
lib/growl.js+25 −26 modified@@ -4,12 +4,11 @@ * Module dependencies. */ -var exec = require('child_process').exec +var spawn = require('child_process').spawn , fs = require('fs') , path = require('path') , exists = fs.existsSync || path.existsSync , os = require('os') - , quote = JSON.stringify , cmd; function which(name) { @@ -127,7 +126,7 @@ exports = module.exports = growl; * Node-growl version. */ -exports.version = '1.4.1' +exports.version = '1.9.3' /** * Send growl notification _msg_ with _options_. @@ -189,18 +188,18 @@ function growl(msg, options, fn) { flag = flag || /^png|gif|jpe?g$/.test(ext) && 'image' flag = flag || ext && (image = ext) && 'icon' flag = flag || 'icon' - args.push('--' + flag, quote(image)) + args.push('--' + flag, image) break; case 'Darwin-NotificationCenter': - args.push(cmd.icon, quote(image)); + args.push(cmd.icon, image); break; case 'Linux': - args.push(cmd.icon, quote(image)); + args.push(cmd.icon, image); // libnotify defaults to sticky, set a hint for transient notifications if (!options.sticky) args.push('--hint=int:transient:1'); break; case 'Windows': - args.push(cmd.icon + quote(image)); + args.push(cmd.icon + image); break; } } @@ -230,61 +229,61 @@ function growl(msg, options, fn) { switch(cmd.type) { case 'Darwin-Growl': args.push(cmd.msg); - args.push(quote(msg).replace(/\\n/g, '\n')); - if (options.title) args.push(quote(options.title)); + args.push(msg.replace(/\\n/g, '\n')); + if (options.title) args.push(options.title); break; case 'Darwin-NotificationCenter': args.push(cmd.msg); - var stringifiedMsg = quote(msg); + var stringifiedMsg = msg; var escapedMsg = stringifiedMsg.replace(/\\n/g, '\n'); args.push(escapedMsg); if (options.title) { args.push(cmd.title); - args.push(quote(options.title)); + args.push(options.title); } if (options.subtitle) { args.push(cmd.subtitle); - args.push(quote(options.subtitle)); + args.push(options.subtitle); } if (options.url) { args.push(cmd.url); - args.push(quote(options.url)); + args.push(options.url); } break; case 'Linux-Growl': args.push(cmd.msg); - args.push(quote(msg).replace(/\\n/g, '\n')); - if (options.title) args.push(quote(options.title)); + args.push(msg.replace(/\\n/g, '\n')); + if (options.title) args.push(options.title); if (cmd.host) { args.push(cmd.host.cmd, cmd.host.hostname) } break; case 'Linux': if (options.title) { - args.push(quote(options.title)); + args.push(options.title); args.push(cmd.msg); - args.push(quote(msg).replace(/\\n/g, '\n')); + args.push(msg.replace(/\\n/g, '\n')); } else { - args.push(quote(msg).replace(/\\n/g, '\n')); + args.push(msg.replace(/\\n/g, '\n')); } break; case 'Windows': - args.push(quote(msg).replace(/\\n/g, '\n')); - if (options.title) args.push(cmd.title + quote(options.title)); - if (options.url) args.push(cmd.url + quote(options.url)); + args.push(msg.replace(/\\n/g, '\n')); + if (options.title) args.push(cmd.title + options.title); + if (options.url) args.push(cmd.url + options.url); break; case 'Custom': args[0] = (function(origCommand) { var message = options.title ? options.title + ': ' + msg : msg; - var command = origCommand.replace(/(^|[^%])%s/g, '$1' + quote(message)); - if (command === origCommand) args.push(quote(message)); + var command = origCommand.replace(/(^|[^%])%s/g, '$1' + message); + if (command === origCommand) args.push(message); return command; })(args[0]); break; } - - // execute - exec(args.join(' '), fn); + var cmd_to_exec = args[0]; + args.shift(); + spawn(cmd_to_exec, args); };
package.json+1 −1 modified@@ -1,6 +1,6 @@ { "name": "growl", - "version": "1.9.2", + "version": "1.9.3", "description": "Growl unobtrusive notifications", "author": "TJ Holowaychuk <tj@vision-media.ca>", "maintainers": [
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
8- github.com/advisories/GHSA-qh2h-chj9-jffqghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2017-16042ghsaADVISORY
- github.com/tj/node-growl/commit/d71177d5331c9de4658aca62e0ac921f178b0669ghsaWEB
- github.com/tj/node-growl/issues/60ghsax_refsource_MISCWEB
- github.com/tj/node-growl/pull/61ghsax_refsource_MISCWEB
- github.com/tj/node-growl/pull/62ghsaWEB
- nodesecurity.io/advisories/146mitrex_refsource_MISC
- www.npmjs.com/advisories/146ghsaWEB
News mentions
0No linked articles in our index yet.