From d71177d5331c9de4658aca62e0ac921f178b0669 Mon Sep 17 00:00:00 2001 From: Zsolt Imre Date: Thu, 13 Jul 2017 11:34:19 +0100 Subject: [PATCH] Fix to resolve the command injection vulnerability. (#62) * fix(lib): fixed command injection vulnerability according to Issue #60 * Removed unnecessary dependency by using child_process spawn() method --- History.md | 5 +++++ lib/growl.js | 51 +++++++++++++++++++++++++-------------------------- package.json | 2 +- 3 files changed, 31 insertions(+), 27 deletions(-) diff --git a/History.md b/History.md index a4b7b49..137f602 100644 --- a/History.md +++ b/History.md @@ -1,4 +1,9 @@ +1.9.3 / 2016-09-05 +================== + + * fixed command injection vulnerability + 1.7.0 / 2012-12-30 ================== diff --git a/lib/growl.js b/lib/growl.js index 719b5af..1d3dfd1 100644 --- a/lib/growl.js +++ b/lib/growl.js @@ -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); }; diff --git a/package.json b/package.json index 962c7fa..c4d68b2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "growl", - "version": "1.9.2", + "version": "1.9.3", "description": "Growl unobtrusive notifications", "author": "TJ Holowaychuk ", "maintainers": [