Skip to content

Commit d71177d

Browse files
keymandlldeiga
authored andcommitted
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
1 parent dc8aae0 commit d71177d

File tree

3 files changed

+31
-27
lines changed

3 files changed

+31
-27
lines changed

History.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11

2+
1.9.3 / 2016-09-05
3+
==================
4+
5+
* fixed command injection vulnerability
6+
27
1.7.0 / 2012-12-30
38
==================
49

lib/growl.js

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@
44
* Module dependencies.
55
*/
66

7-
var exec = require('child_process').exec
7+
var spawn = require('child_process').spawn
88
, fs = require('fs')
99
, path = require('path')
1010
, exists = fs.existsSync || path.existsSync
1111
, os = require('os')
12-
, quote = JSON.stringify
1312
, cmd;
1413

1514
function which(name) {
@@ -127,7 +126,7 @@ exports = module.exports = growl;
127126
* Node-growl version.
128127
*/
129128

130-
exports.version = '1.4.1'
129+
exports.version = '1.9.3'
131130

132131
/**
133132
* Send growl notification _msg_ with _options_.
@@ -189,18 +188,18 @@ function growl(msg, options, fn) {
189188
flag = flag || /^png|gif|jpe?g$/.test(ext) && 'image'
190189
flag = flag || ext && (image = ext) && 'icon'
191190
flag = flag || 'icon'
192-
args.push('--' + flag, quote(image))
191+
args.push('--' + flag, image)
193192
break;
194193
case 'Darwin-NotificationCenter':
195-
args.push(cmd.icon, quote(image));
194+
args.push(cmd.icon, image);
196195
break;
197196
case 'Linux':
198-
args.push(cmd.icon, quote(image));
197+
args.push(cmd.icon, image);
199198
// libnotify defaults to sticky, set a hint for transient notifications
200199
if (!options.sticky) args.push('--hint=int:transient:1');
201200
break;
202201
case 'Windows':
203-
args.push(cmd.icon + quote(image));
202+
args.push(cmd.icon + image);
204203
break;
205204
}
206205
}
@@ -230,61 +229,61 @@ function growl(msg, options, fn) {
230229
switch(cmd.type) {
231230
case 'Darwin-Growl':
232231
args.push(cmd.msg);
233-
args.push(quote(msg).replace(/\\n/g, '\n'));
234-
if (options.title) args.push(quote(options.title));
232+
args.push(msg.replace(/\\n/g, '\n'));
233+
if (options.title) args.push(options.title);
235234
break;
236235
case 'Darwin-NotificationCenter':
237236
args.push(cmd.msg);
238-
var stringifiedMsg = quote(msg);
237+
var stringifiedMsg = msg;
239238
var escapedMsg = stringifiedMsg.replace(/\\n/g, '\n');
240239
args.push(escapedMsg);
241240
if (options.title) {
242241
args.push(cmd.title);
243-
args.push(quote(options.title));
242+
args.push(options.title);
244243
}
245244
if (options.subtitle) {
246245
args.push(cmd.subtitle);
247-
args.push(quote(options.subtitle));
246+
args.push(options.subtitle);
248247
}
249248
if (options.url) {
250249
args.push(cmd.url);
251-
args.push(quote(options.url));
250+
args.push(options.url);
252251
}
253252
break;
254253
case 'Linux-Growl':
255254
args.push(cmd.msg);
256-
args.push(quote(msg).replace(/\\n/g, '\n'));
257-
if (options.title) args.push(quote(options.title));
255+
args.push(msg.replace(/\\n/g, '\n'));
256+
if (options.title) args.push(options.title);
258257
if (cmd.host) {
259258
args.push(cmd.host.cmd, cmd.host.hostname)
260259
}
261260
break;
262261
case 'Linux':
263262
if (options.title) {
264-
args.push(quote(options.title));
263+
args.push(options.title);
265264
args.push(cmd.msg);
266-
args.push(quote(msg).replace(/\\n/g, '\n'));
265+
args.push(msg.replace(/\\n/g, '\n'));
267266
} else {
268-
args.push(quote(msg).replace(/\\n/g, '\n'));
267+
args.push(msg.replace(/\\n/g, '\n'));
269268
}
270269
break;
271270
case 'Windows':
272-
args.push(quote(msg).replace(/\\n/g, '\n'));
273-
if (options.title) args.push(cmd.title + quote(options.title));
274-
if (options.url) args.push(cmd.url + quote(options.url));
271+
args.push(msg.replace(/\\n/g, '\n'));
272+
if (options.title) args.push(cmd.title + options.title);
273+
if (options.url) args.push(cmd.url + options.url);
275274
break;
276275
case 'Custom':
277276
args[0] = (function(origCommand) {
278277
var message = options.title
279278
? options.title + ': ' + msg
280279
: msg;
281-
var command = origCommand.replace(/(^|[^%])%s/g, '$1' + quote(message));
282-
if (command === origCommand) args.push(quote(message));
280+
var command = origCommand.replace(/(^|[^%])%s/g, '$1' + message);
281+
if (command === origCommand) args.push(message);
283282
return command;
284283
})(args[0]);
285284
break;
286285
}
287-
288-
// execute
289-
exec(args.join(' '), fn);
286+
var cmd_to_exec = args[0];
287+
args.shift();
288+
spawn(cmd_to_exec, args);
290289
};

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "growl",
3-
"version": "1.9.2",
3+
"version": "1.9.3",
44
"description": "Growl unobtrusive notifications",
55
"author": "TJ Holowaychuk <[email protected]>",
66
"maintainers": [

0 commit comments

Comments
 (0)