Skip to content
This repository has been archived by the owner on Jun 2, 2022. It is now read-only.

Commit

Permalink
feat: add config and test for methods detection
Browse files Browse the repository at this point in the history
  • Loading branch information
AH7 committed Aug 20, 2018
1 parent 4439340 commit 3def72a
Show file tree
Hide file tree
Showing 17 changed files with 7,114 additions and 105 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules/
.npmignore
.vscode/
69 changes: 41 additions & 28 deletions lib/ast.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,50 +4,63 @@ var acorn = require('acorn');
function findAllVulnerableFunctionsInScriptPath(
scriptPath, vulnerableFunctionNames) {
var scriptContent = fs.readFileSync(scriptPath);
var parsedScript = acorn.parse(scriptContent, {locations:true});
var decleardFunctions = {};
var body = parsedScript.body;
body.forEach((node) => {
var loc, name;
if (node.type === 'FunctionDeclaration') {
loc = node.body.loc.start;
name = node.id.name;
if (vulnerableFunctionNames.includes(name)) {
decleardFunctions[name] = loc;
}
} else if ((node.type === 'ExpressionStatement' &&
node.expression.right &&
node.expression.right.type === 'FunctionExpression')) {
try {
try {
var parsedScript = acorn.parse(scriptContent,
{locations:true, sourceType: 'module'});
var body = parsedScript.body;
body.forEach(function (node) {
var loc, name;
if (node.type === 'FunctionDeclaration') {
loc = node.body.loc.start;
name = node.id.name;
if (vulnerableFunctionNames.includes(name)) {
decleardFunctions[name] = loc;
}
} else if ((node.type === 'ExpressionStatement' &&
node.expression.right &&
node.expression.right.type === 'FunctionExpression')) {
loc = node.expression.right.body.loc.start;
// Todo: going recrusively over object
// Todo: going recursively over object
if (node.expression.left.object.object &&
node.expression.left.object.object.name) {
name = node.expression.left.object.object.name;
name = name + '.' + node.expression.left.object.property.name;
} else {
name = node.expression.left.object.name;
}

name = name + '.' + node.expression.left.property.name;
if (vulnerableFunctionNames.includes(name)) {
decleardFunctions[name] = loc;
}
} catch (error) {
console.log(error);
}
} else if (node.type === 'VariableDeclaration') {
node.declarations.forEach((decl) => {
if (decl.init && decl.init.type === 'FunctionExpression') {
name = decl.init.id.name;
loc = decl.init.body.loc.start;
} else if (node.type === 'VariableDeclaration') {
node.declarations.forEach((decl) => {
if (decl.init && decl.init.type === 'FunctionExpression') {
if (decl.init.id && decl.init.id.name) {
name = decl.init.id.name;
} else {
name = decl.id.name;
}
loc = decl.init.body.loc.start;
if (vulnerableFunctionNames.includes(name)) {
decleardFunctions[name] = loc;
}
}
});
} else if (node.type === 'ExportNamedDeclaration') {
if (node.declaration.type === 'FunctionDeclaration') {
name = node.declaration.id.name;
loc = node.declaration.body.loc.start;
if (vulnerableFunctionNames.includes(name)) {
decleardFunctions[name] = loc;
}
}
});
}
});
};
});
} catch (error) {
console.log(error);
}
return decleardFunctions;
}
};

module.exports = {findAllVulnerableFunctionsInScriptPath};
39 changes: 3 additions & 36 deletions lib/debugger.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,55 +47,22 @@ function start() {
session.post('Debugger.enable');
session.post('Debugger.setBreakpointsActive', {active: true});

session.on('Debugger.scriptParsed', (script) => {
try {
loadedScripts[script.params.scriptId] = script.params;
var scriptPath = script.params.url;

// dealing only with 3rd party modules.
if (moduleUtils.isNative(scriptPath)) {
return;
}

var moduleInfo = moduleUtils.getModuleInfo(scriptPath);
if (vulnMgmt.isVulnerableModulePath(moduleInfo)) {
var vulnerableMethods =
vulnMgmt.getVulnerableMethodsLocations(moduleInfo, scriptPath);
Object.keys(vulnerableMethods).forEach((methodName) => {
var methodLocation = vulnerableMethods[methodName];
setBreakpointsOnVulnearbleMethods(
script.params.url, moduleInfo, methodName, methodLocation);
});
}
} catch (error) {
console.log(error);
}
});
session.on('Debugger.paused', (message) => {
try {
handleDebuggerPausedEvent(message.params);
} catch (error) {
console.log(error);
}
});
session.post('Debugger.enable');
session.post('Debugger.setBreakpointsActive', {active: true});

function setBreakpointsOnVulnearbleMethods(
moduleUrl, moduleInfo, methodName, methodLocation) {
console.log(methodLocation);
session.post('Debugger.setBreakpointByUrl',
{
lineNumber: methodLocation.line,
columnNumber: 0,
url: moduleUrl,
condition: undefined,
}, (error,response) => {
if (!error) {
if (!error) {
breakpointsMap[response.breakpointId] = {
methodName,
moduleInfo,
};
console.log('Added breakpoint to ' + methodName +
' in module ' + moduleInfo.name +'@' + moduleInfo.version);
} else {
console.log(error);
}
Expand Down
10 changes: 7 additions & 3 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
var debug = require('./debugger');
var transmitter = require('./transmitter');

function start(options) {
transmitter.start(options.projectId);
debug.start();
function start(config) {
try {
transmitter.start(config.url, config.projectId);
debug.start();
} catch (error) {
console.log(error);
};
}

module.exports = start;
8 changes: 5 additions & 3 deletions lib/transmitter.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
var needle = require('needle');

var eventsToSend = [];
function start(projectId) {
function start(url, projectId) {
var INERVAL_TIMEOUT = 60000; // 60 seconds
setInterval(() => {
transmitData();
eventsToSend = [];
}, 60000);
}, INERVAL_TIMEOUT);

function transmitData() {
if (eventsToSend.length === 0) {
return;
}
needle.post(
'https://homebase.dev.snyk.io/beacon',
url,
{projectId, eventsToSend},
{json: true}
);
Expand All @@ -21,6 +22,7 @@ function start(projectId) {

function addEvent(event) {
eventsToSend.push(event);
console.log('Method was called', event);
}

module.exports = {start,addEvent};
27 changes: 19 additions & 8 deletions lib/vuln-mgmt.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ function loadVulnerabiltiesMetadata() {

function isVulnerableModulePath(moduleInfo) {
var name = moduleInfo.name;
var version = moduleInfo.version;;
var version = moduleInfo.version;
var scriptRelativePath = moduleInfo.scriptRelativePath;
if (!((name in vulnerabiltiesMetadata) &&
(scriptRelativePath in vulnerabiltiesMetadata[name]))) {
Expand All @@ -27,8 +27,13 @@ function isVulnerableModulePath(moduleInfo) {
vulnerabiltiesMetadata[name][scriptRelativePath];
var foundVulnerableMethod = false;
scriptPathMethods.forEach(value => {
foundVulnerableMethod =
foundVulnerableMethod || semver.satisfies(version, value.semver);
value.semver.some(ver => {
if (semver.satisfies(version, ver)) {
foundVulnerableMethod = foundVulnerableMethod || true;
}

return false;
});
});
return foundVulnerableMethod;
}
Expand All @@ -42,14 +47,20 @@ function getVulnerableMethodsLocations(moduleInfo, scriptPath) {
var scriptPathMethods =
vulnerabiltiesMetadata[name][scriptRelativePath];
scriptPathMethods.forEach(value => {
if (semver.satisfies(version, value.semver)) {
vulnerableFunctionNames =
vulnerableFunctionNames.concat(value.name);
}
value.semver.some(ver => {
if (semver.satisfies(version, ver)) {
vulnerableFunctionNames =
vulnerableFunctionNames.concat(value.name);
return true;
}

return false;
});
});

var functionsLocationInScript =
ast.findAllVulnerableFunctionsInScriptPath(
scriptPath,vulnerableFunctionNames);
scriptPath, vulnerableFunctionNames);
return functionsLocationInScript;
}

Expand Down
36 changes: 22 additions & 14 deletions methods.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,64 +2,72 @@
"st": {
"st.js" : [
{
"name" : ["getPath"],
"semver": "<0.2.5"
"name" : ["Mount.prototype.getPath"],
"semver": ["<0.2.5"],
"id": "npm:st:20140206"
}
]
},
"superagent": {
"lib/node/index.js" : [
{
"name" : ["Request.prototype._end"],
"semver": "<3.7.0"
"semver": ["<3.7.0"],
"id": "npm:superagent:20170807"
}
]
},
"qs": {
"lib/parse.js" : [
{
"name": ["parseObject"],
"semver": "<6.3.2 >=6.3.0 || <6.2.3 >=6.2.0 || <6.1.2 >=6.1.0 || <6.0.4"
"semver": ["<6.3.2 >=6.3.0","<6.2.3 >=6.2.0","<6.1.2 >=6.1.","<6.0.4"],
"id": "npm:qs:20170213"
}
]
},
"tough-cookie": {
"tough-cookie": {
"lib/cookie.js" : [
{
"name" : ["Parse"],
"semver": "<2.3.3"
}
"name" : ["parse"],
"semver": ["<2.3.3"],
"id": "npm:tough-cookie:20170905"
}
]
},
"uglify-js": {
"lib/parse.js" : [
{
"name": ["parse_js_numbers"],
"semver": "<2.6.0"
"name": ["parse_js_number"],
"semver": ["<2.6.0"],
"id": "npm:uglify-js:20151024"
}
]
},
"ms": {
"index.js" : [
{
"name": ["parse"],
"semver": "<2.0.0"
}
"semver": ["<2.0.0"],
"id": "npm:ms:20170412"
}
]
},
"handlebars": {
"lib/handelbars/utils.js" : [
{
"name": ["escapeExpression"],
"semver": ["<4.0.0"]
"semver": ["<4.0.0"],
"id": "npm:handlebars:20151207"
}
]
},
"debug": {
"src/node.js" : [
{
"name": ["exports.formatters.o"],
"semver": ["<2.6.9 || >=3.0.0 <3.1.0"]
"semver": ["<2.6.9",">=3.0.0 <3.1.0"],
"id": "npm:debug:20170905"
}
]
}
Expand Down
Loading

0 comments on commit 3def72a

Please sign in to comment.