Comparing version 0.0.4 to 0.0.5
@@ -8,6 +8,9 @@ /* | ||
var child = require('child_process'), | ||
path = require('path'); | ||
path = require('path'), | ||
whitelist; | ||
function isAbsolutePath(command) { | ||
return command.charAt(0) === path.sep; | ||
} | ||
/* | ||
@@ -31,3 +34,3 @@ * For each whitelist path, add these commands | ||
typeof thisCommand === 'string' | ||
&& thisCommand.charAt(0) === '/') { | ||
&& isAbsolutePath(thisCommand)) { | ||
return thisCommand; | ||
@@ -44,2 +47,18 @@ } else { | ||
function Whitelist() { | ||
this.commands = []; | ||
this.commandPaths = []; | ||
} | ||
Whitelist.prototype.set = function(commands, paths) { | ||
this.commands = commands || []; | ||
paths = paths || '/usr/local/bin'; | ||
paths = (paths instanceof Array) ? paths : [paths]; | ||
this.commandPaths = getPathCombinations(commands, paths); | ||
}; | ||
whitelist = new Whitelist(); | ||
/* | ||
@@ -49,7 +68,6 @@ * Returns a function which throws the exception if not in whitelist | ||
*/ | ||
function permissionDenied(name, originalMethod, whitelistPaths, whitelistCommandPaths) { | ||
function permissionDenied(name, originalMethod) { | ||
return function () { | ||
var toCheckCommands = [], | ||
toCheckCommandPaths, | ||
found = false, | ||
@@ -64,9 +82,15 @@ i = 0; | ||
} | ||
toCheckCommandPaths | ||
= getPathCombinations(toCheckCommands, whitelistPaths); | ||
for (i = 0; i < toCheckCommandPaths.length; i++) { | ||
if (whitelistCommandPaths.indexOf(toCheckCommandPaths[i]) >= 0) { | ||
found = true; | ||
break; | ||
for (i = 0; i < toCheckCommands.length; i++) { | ||
if (isAbsolutePath(toCheckCommands[i])) { | ||
if (whitelist.commandPaths.indexOf(toCheckCommands[i]) >= 0) { | ||
found = true; | ||
break; | ||
} | ||
} else { | ||
//relative path | ||
if (whitelist.commands.indexOf(path.basename(toCheckCommands[i])) >= 0) { | ||
found = true; | ||
break; | ||
} | ||
} | ||
@@ -92,5 +116,2 @@ } | ||
var origBinding, | ||
whitelistCommands = [], | ||
whitelistPaths, | ||
whitelistCommandPaths = [], | ||
originalMethod, | ||
@@ -100,12 +121,5 @@ fn; | ||
origBinding = process.binding; | ||
whitelistCommands = config.whitelist ? config.whitelist : []; | ||
whitelistPaths = config.whitelistPath ? config.whitelistPath : '/usr/local/bin'; | ||
whitelist.set(config.whitelist, config.whitelistPath); | ||
// Make sure its an array | ||
whitelistPaths = (whitelistPaths instanceof Array) ? whitelistPaths : [whitelistPaths]; | ||
// Generate a fully qualified whitelisted commands | ||
whitelistCommandPaths | ||
= getPathCombinations(whitelistCommands, whitelistPaths); | ||
process.binding = function (name) { | ||
@@ -125,3 +139,3 @@ if (name === 'process_wrap') { | ||
originalMethod = child[fn]; | ||
child[fn] = permissionDenied(fn, originalMethod, whitelistPaths, whitelistCommandPaths); | ||
child[fn] = permissionDenied(fn, originalMethod); | ||
} | ||
@@ -138,1 +152,4 @@ } | ||
module.exports = restrict; | ||
module.exports.setWhitelist = function() { | ||
whitelist.set(arguments); | ||
}; |
{ | ||
"name": "restrict", | ||
"description": "Restricts applications from calling certain methods on process and all methods on child_process", | ||
"version": "0.0.4", | ||
"version": "0.0.5", | ||
"author": "Rohini Harendra <rohini.raghav@gmail.com>", | ||
@@ -26,5 +26,5 @@ "repository": { | ||
"devDependencies": { | ||
"jshint": "~0.9.0", | ||
"yui-lint": "~0.1.1", | ||
"istanbul": "~0.1.8", | ||
"jshint": "*", | ||
"yui-lint": "*", | ||
"istanbul": "*", | ||
"vows": "*" | ||
@@ -31,0 +31,0 @@ }, |
@@ -26,2 +26,5 @@ # restrict | ||
//set whitelist can be invoked, if the whitelist is dynamic | ||
restrict.setWhitelist(['grep'], ['/bin', '/usr/bin']); | ||
var child_process = require('child_process'); | ||
@@ -28,0 +31,0 @@ try { |
@@ -12,3 +12,3 @@ /* | ||
restrict({ | ||
'whitelist': ['ls'], | ||
'whitelist': ['ls', 'foo.bar'], | ||
'whitelistPath': ['/bin', '/usr/bin'] | ||
@@ -45,2 +45,23 @@ }); | ||
} | ||
}, | ||
'verify error': function (topic) { | ||
assert.ok(topic.error === undefined); | ||
} | ||
}, | ||
'testing restrict child_process methods relative whitelist': { | ||
topic: function () { | ||
var self = this; | ||
try { | ||
require('child_process').exec('xyz/foo.bar',['-ltr']); | ||
require('child_process').exec('./foo.bar',['-ltr']); | ||
require('child_process').exec('../foo.bar',['-ltr']); | ||
require('child_process').exec('./tmp/foo.bar',['-ltr']); | ||
require('child_process').exec('foo.bar',['-ltr']); | ||
self.callback(null, {}); | ||
} catch (e) { | ||
self.callback(null, { | ||
'error': e | ||
}); | ||
} | ||
@@ -51,3 +72,3 @@ }, | ||
} | ||
}, | ||
}, | ||
'testing restrict child_process methods whitelist absolute': { | ||
@@ -139,2 +160,40 @@ topic: function () { | ||
} | ||
vows.describe('restrict').addBatch(tests).export(module); | ||
var tests_next = { | ||
'testing restrict with setWhitelist child_process methods whitelist': { | ||
topic: function () { | ||
var self = this; | ||
restrict.setWhitelist(['grep'], ['/bin', '/usr/bin']); | ||
try { | ||
require('child_process').spawn('grep',['BLA', './*']); | ||
} catch (e) { | ||
self.callback(null, { | ||
'error': e | ||
}); | ||
} | ||
}, | ||
'verify error': function (topic) { | ||
assert.ok(topic.error === undefined); | ||
} | ||
}, | ||
'testing restrict with setWhitelist child_process methods non-whitelist': { | ||
topic: function () { | ||
var self = this; | ||
try { | ||
restrict.setWhitelist(['grep'], ['/bin', '/usr/bin']); | ||
require('child_process').exec('ls',['-ltr']); | ||
self.callback(null, {}); | ||
} catch (e) { | ||
self.callback(null, { | ||
'error': e | ||
}); | ||
} | ||
}, | ||
'verify error': function (topic) { | ||
assert.ok(topic.error !== null); | ||
} | ||
}, | ||
} | ||
vows.describe('restrict').addBatch(tests).addBatch(tests_next).export(module); |
Sorry, the diff of this file is not supported yet
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
13093
330
57
13