Skip to content

Commit aea7054

Browse files
committed
modified query and added tests
1 parent 7bb11b8 commit aea7054

File tree

6 files changed

+70
-6
lines changed

6 files changed

+70
-6
lines changed

javascript/ql/lib/semmle/javascript/security/dataflow/UnvalidatedDynamicMethodCallQuery.qll

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,12 @@ class Configuration extends TaintTracking::Configuration {
5858
// avoid overlapping results with unsafe dynamic method access query
5959
not PropertyInjection::hasUnsafeMethods(read.getBase().getALocalSource())
6060
)
61+
or
62+
exists(DataFlow::SourceNode base, DataFlow::CallNode get | get = base.getAMethodCall("get") |
63+
src = get.getArgument(0) and
64+
dst = get
65+
) and
66+
srclabel.isTaint() and
67+
dstlabel instanceof MaybeNonFunction
6168
}
6269
}

javascript/ql/src/Security/CWE-754/examples/UnvalidatedDynamicMethodCallGood.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ actions.put("pause", function pause(data) {
1111

1212
app.get('/perform/:action/:payload', function(req, res) {
1313
if (actions.has(req.params.action)) {
14-
let action = actions.get(req.params.action);
14+
if (typeof actions.get(req.params.action) === 'function'){
15+
let action = actions.get(req.params.action);
16+
}
1517
// GOOD: `action` is either the `play` or the `pause` function from above
1618
res.end(action(req.params.payload));
1719
} else {
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
var express = require('express');
2+
var app = express();
3+
4+
var actions = new Map();
5+
actions.put("play", function play(data) {
6+
// ...
7+
});
8+
actions.put("pause", function pause(data) {
9+
// ...
10+
});
11+
12+
app.get('/perform/:action/:payload', function(req, res) {
13+
let action = actions.get(req.params.action);
14+
res.end(action.get(req.params.payload)); // NOT OK
15+
});
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
var express = require('express');
2+
var app = express();
3+
4+
var actions = new Map();
5+
actions.put("play", function play(data) {
6+
// ...
7+
});
8+
actions.put("pause", function pause(data) {
9+
// ...
10+
});
11+
12+
app.get('/perform/:action/:payload', function(req, res) {
13+
if (actions.has(req.params.action)){
14+
let action = actions.get(req.params.action);
15+
res.end(action.get(req.params.payload)); // NOT OK, but not flagged [INCONSISTENCY]
16+
}
17+
});

javascript/ql/test/query-tests/Security/CWE-754/UnvalidatedDynamicMethodCallGood.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,20 @@ var express = require('express');
22
var app = express();
33

44
var actions = new Map();
5-
actions.put("play", function (data) {
5+
actions.put("play", function play(data) {
66
// ...
77
});
8-
actions.put("pause", function(data) {
8+
actions.put("pause", function pause(data) {
99
// ...
1010
});
1111

12-
app.get('/perform/:action/:payload', function(req, res) {
12+
app.get('/perform/:action/:payload', function (req, res) {
1313
if (actions.has(req.params.action)) {
14-
let action = actions.get(req.params.action);
15-
res.end(action(req.params.payload));
14+
if (typeof actions.get(req.params.action) === 'function') {
15+
let action = actions.get(req.params.action);
16+
// GOOD: `action` is either the `play` or the `pause` function from above
17+
res.end(action(req.params.payload));
18+
}
1619
} else {
1720
res.end("Unsupported action.");
1821
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
var express = require('express');
2+
var app = express();
3+
4+
var actions = new Map();
5+
actions.put("play", function play(data) {
6+
// ...
7+
});
8+
actions.put("pause", function pause(data) {
9+
// ...
10+
});
11+
12+
app.get('/perform/:action/:payload', function (req, res) {
13+
if (typeof actions.get(req.params.action) === 'function') {
14+
let action = actions.get(req.params.action);
15+
// GOOD: `action` is either the `play` or the `pause` function from above
16+
res.end(action(req.params.payload));
17+
} else {
18+
res.end("Unsupported action.");
19+
}
20+
});

0 commit comments

Comments
 (0)