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

Commit 3def72a

Browse files
committed
feat: add config and test for methods detection
1 parent 4439340 commit 3def72a

File tree

17 files changed

+7114
-105
lines changed

17 files changed

+7114
-105
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules/
2+
.npmignore
3+
.vscode/

lib/ast.js

Lines changed: 41 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,50 +4,63 @@ var acorn = require('acorn');
44
function findAllVulnerableFunctionsInScriptPath(
55
scriptPath, vulnerableFunctionNames) {
66
var scriptContent = fs.readFileSync(scriptPath);
7-
var parsedScript = acorn.parse(scriptContent, {locations:true});
87
var decleardFunctions = {};
9-
var body = parsedScript.body;
10-
body.forEach((node) => {
11-
var loc, name;
12-
if (node.type === 'FunctionDeclaration') {
13-
loc = node.body.loc.start;
14-
name = node.id.name;
15-
if (vulnerableFunctionNames.includes(name)) {
16-
decleardFunctions[name] = loc;
17-
}
18-
} else if ((node.type === 'ExpressionStatement' &&
19-
node.expression.right &&
20-
node.expression.right.type === 'FunctionExpression')) {
21-
try {
8+
try {
9+
var parsedScript = acorn.parse(scriptContent,
10+
{locations:true, sourceType: 'module'});
11+
var body = parsedScript.body;
12+
body.forEach(function (node) {
13+
var loc, name;
14+
if (node.type === 'FunctionDeclaration') {
15+
loc = node.body.loc.start;
16+
name = node.id.name;
17+
if (vulnerableFunctionNames.includes(name)) {
18+
decleardFunctions[name] = loc;
19+
}
20+
} else if ((node.type === 'ExpressionStatement' &&
21+
node.expression.right &&
22+
node.expression.right.type === 'FunctionExpression')) {
2223
loc = node.expression.right.body.loc.start;
23-
// Todo: going recrusively over object
24+
// Todo: going recursively over object
2425
if (node.expression.left.object.object &&
2526
node.expression.left.object.object.name) {
2627
name = node.expression.left.object.object.name;
2728
name = name + '.' + node.expression.left.object.property.name;
2829
} else {
2930
name = node.expression.left.object.name;
3031
}
31-
3232
name = name + '.' + node.expression.left.property.name;
3333
if (vulnerableFunctionNames.includes(name)) {
3434
decleardFunctions[name] = loc;
3535
}
36-
} catch (error) {
37-
console.log(error);
38-
}
39-
} else if (node.type === 'VariableDeclaration') {
40-
node.declarations.forEach((decl) => {
41-
if (decl.init && decl.init.type === 'FunctionExpression') {
42-
name = decl.init.id.name;
43-
loc = decl.init.body.loc.start;
36+
} else if (node.type === 'VariableDeclaration') {
37+
node.declarations.forEach((decl) => {
38+
if (decl.init && decl.init.type === 'FunctionExpression') {
39+
if (decl.init.id && decl.init.id.name) {
40+
name = decl.init.id.name;
41+
} else {
42+
name = decl.id.name;
43+
}
44+
loc = decl.init.body.loc.start;
45+
if (vulnerableFunctionNames.includes(name)) {
46+
decleardFunctions[name] = loc;
47+
}
48+
}
49+
});
50+
} else if (node.type === 'ExportNamedDeclaration') {
51+
if (node.declaration.type === 'FunctionDeclaration') {
52+
name = node.declaration.id.name;
53+
loc = node.declaration.body.loc.start;
4454
if (vulnerableFunctionNames.includes(name)) {
4555
decleardFunctions[name] = loc;
4656
}
4757
}
48-
});
49-
}
50-
});
58+
};
59+
});
60+
} catch (error) {
61+
console.log(error);
62+
}
5163
return decleardFunctions;
52-
}
64+
};
65+
5366
module.exports = {findAllVulnerableFunctionsInScriptPath};

lib/debugger.js

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -47,55 +47,22 @@ function start() {
4747
session.post('Debugger.enable');
4848
session.post('Debugger.setBreakpointsActive', {active: true});
4949

50-
session.on('Debugger.scriptParsed', (script) => {
51-
try {
52-
loadedScripts[script.params.scriptId] = script.params;
53-
var scriptPath = script.params.url;
54-
55-
// dealing only with 3rd party modules.
56-
if (moduleUtils.isNative(scriptPath)) {
57-
return;
58-
}
59-
60-
var moduleInfo = moduleUtils.getModuleInfo(scriptPath);
61-
if (vulnMgmt.isVulnerableModulePath(moduleInfo)) {
62-
var vulnerableMethods =
63-
vulnMgmt.getVulnerableMethodsLocations(moduleInfo, scriptPath);
64-
Object.keys(vulnerableMethods).forEach((methodName) => {
65-
var methodLocation = vulnerableMethods[methodName];
66-
setBreakpointsOnVulnearbleMethods(
67-
script.params.url, moduleInfo, methodName, methodLocation);
68-
});
69-
}
70-
} catch (error) {
71-
console.log(error);
72-
}
73-
});
74-
session.on('Debugger.paused', (message) => {
75-
try {
76-
handleDebuggerPausedEvent(message.params);
77-
} catch (error) {
78-
console.log(error);
79-
}
80-
});
81-
session.post('Debugger.enable');
82-
session.post('Debugger.setBreakpointsActive', {active: true});
83-
8450
function setBreakpointsOnVulnearbleMethods(
8551
moduleUrl, moduleInfo, methodName, methodLocation) {
86-
console.log(methodLocation);
8752
session.post('Debugger.setBreakpointByUrl',
8853
{
8954
lineNumber: methodLocation.line,
9055
columnNumber: 0,
9156
url: moduleUrl,
9257
condition: undefined,
9358
}, (error,response) => {
94-
if (!error) {
59+
if (!error) {
9560
breakpointsMap[response.breakpointId] = {
9661
methodName,
9762
moduleInfo,
9863
};
64+
console.log('Added breakpoint to ' + methodName +
65+
' in module ' + moduleInfo.name +'@' + moduleInfo.version);
9966
} else {
10067
console.log(error);
10168
}

lib/index.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
var debug = require('./debugger');
22
var transmitter = require('./transmitter');
33

4-
function start(options) {
5-
transmitter.start(options.projectId);
6-
debug.start();
4+
function start(config) {
5+
try {
6+
transmitter.start(config.url, config.projectId);
7+
debug.start();
8+
} catch (error) {
9+
console.log(error);
10+
};
711
}
812

913
module.exports = start;

lib/transmitter.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
var needle = require('needle');
22

33
var eventsToSend = [];
4-
function start(projectId) {
4+
function start(url, projectId) {
5+
var INERVAL_TIMEOUT = 60000; // 60 seconds
56
setInterval(() => {
67
transmitData();
78
eventsToSend = [];
8-
}, 60000);
9+
}, INERVAL_TIMEOUT);
910

1011
function transmitData() {
1112
if (eventsToSend.length === 0) {
1213
return;
1314
}
1415
needle.post(
15-
'https://homebase.dev.snyk.io/beacon',
16+
url,
1617
{projectId, eventsToSend},
1718
{json: true}
1819
);
@@ -21,6 +22,7 @@ function start(projectId) {
2122

2223
function addEvent(event) {
2324
eventsToSend.push(event);
25+
console.log('Method was called', event);
2426
}
2527

2628
module.exports = {start,addEvent};

lib/vuln-mgmt.js

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ function loadVulnerabiltiesMetadata() {
1717

1818
function isVulnerableModulePath(moduleInfo) {
1919
var name = moduleInfo.name;
20-
var version = moduleInfo.version;;
20+
var version = moduleInfo.version;
2121
var scriptRelativePath = moduleInfo.scriptRelativePath;
2222
if (!((name in vulnerabiltiesMetadata) &&
2323
(scriptRelativePath in vulnerabiltiesMetadata[name]))) {
@@ -27,8 +27,13 @@ function isVulnerableModulePath(moduleInfo) {
2727
vulnerabiltiesMetadata[name][scriptRelativePath];
2828
var foundVulnerableMethod = false;
2929
scriptPathMethods.forEach(value => {
30-
foundVulnerableMethod =
31-
foundVulnerableMethod || semver.satisfies(version, value.semver);
30+
value.semver.some(ver => {
31+
if (semver.satisfies(version, ver)) {
32+
foundVulnerableMethod = foundVulnerableMethod || true;
33+
}
34+
35+
return false;
36+
});
3237
});
3338
return foundVulnerableMethod;
3439
}
@@ -42,14 +47,20 @@ function getVulnerableMethodsLocations(moduleInfo, scriptPath) {
4247
var scriptPathMethods =
4348
vulnerabiltiesMetadata[name][scriptRelativePath];
4449
scriptPathMethods.forEach(value => {
45-
if (semver.satisfies(version, value.semver)) {
46-
vulnerableFunctionNames =
47-
vulnerableFunctionNames.concat(value.name);
48-
}
50+
value.semver.some(ver => {
51+
if (semver.satisfies(version, ver)) {
52+
vulnerableFunctionNames =
53+
vulnerableFunctionNames.concat(value.name);
54+
return true;
55+
}
56+
57+
return false;
58+
});
4959
});
60+
5061
var functionsLocationInScript =
5162
ast.findAllVulnerableFunctionsInScriptPath(
52-
scriptPath,vulnerableFunctionNames);
63+
scriptPath, vulnerableFunctionNames);
5364
return functionsLocationInScript;
5465
}
5566

methods.json

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,64 +2,72 @@
22
"st": {
33
"st.js" : [
44
{
5-
"name" : ["getPath"],
6-
"semver": "<0.2.5"
5+
"name" : ["Mount.prototype.getPath"],
6+
"semver": ["<0.2.5"],
7+
"id": "npm:st:20140206"
78
}
89
]
910
},
1011
"superagent": {
1112
"lib/node/index.js" : [
1213
{
1314
"name" : ["Request.prototype._end"],
14-
"semver": "<3.7.0"
15+
"semver": ["<3.7.0"],
16+
"id": "npm:superagent:20170807"
1517
}
1618
]
1719
},
1820
"qs": {
1921
"lib/parse.js" : [
2022
{
2123
"name": ["parseObject"],
22-
"semver": "<6.3.2 >=6.3.0 || <6.2.3 >=6.2.0 || <6.1.2 >=6.1.0 || <6.0.4"
24+
"semver": ["<6.3.2 >=6.3.0","<6.2.3 >=6.2.0","<6.1.2 >=6.1.","<6.0.4"],
25+
"id": "npm:qs:20170213"
2326
}
2427
]
2528
},
26-
"tough-cookie": {
29+
"tough-cookie": {
2730
"lib/cookie.js" : [
2831
{
29-
"name" : ["Parse"],
30-
"semver": "<2.3.3"
31-
}
32+
"name" : ["parse"],
33+
"semver": ["<2.3.3"],
34+
"id": "npm:tough-cookie:20170905"
35+
}
3236
]
3337
},
3438
"uglify-js": {
3539
"lib/parse.js" : [
3640
{
37-
"name": ["parse_js_numbers"],
38-
"semver": "<2.6.0"
41+
"name": ["parse_js_number"],
42+
"semver": ["<2.6.0"],
43+
"id": "npm:uglify-js:20151024"
3944
}
4045
]
4146
},
4247
"ms": {
4348
"index.js" : [
4449
{
4550
"name": ["parse"],
46-
"semver": "<2.0.0"
47-
}
51+
"semver": ["<2.0.0"],
52+
"id": "npm:ms:20170412"
53+
}
4854
]
4955
},
5056
"handlebars": {
5157
"lib/handelbars/utils.js" : [
5258
{
5359
"name": ["escapeExpression"],
54-
"semver": ["<4.0.0"]
60+
"semver": ["<4.0.0"],
61+
"id": "npm:handlebars:20151207"
5562
}
5663
]
5764
},
5865
"debug": {
5966
"src/node.js" : [
6067
{
6168
"name": ["exports.formatters.o"],
62-
"semver": ["<2.6.9 || >=3.0.0 <3.1.0"]
69+
"semver": ["<2.6.9",">=3.0.0 <3.1.0"],
70+
"id": "npm:debug:20170905"
6371
}
6472
]
6573
}

0 commit comments

Comments
 (0)