Skip to content

Commit aae92ad

Browse files
committed
JS: add test for DatabaseAccess
1 parent 6b9bd8b commit aae92ad

3 files changed

Lines changed: 67 additions & 2 deletions

File tree

javascript/ql/src/semmle/javascript/frameworks/NoSQL.qll

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,11 @@ private module Mongoose {
429429
)
430430
}
431431

432+
/**
433+
* Gets a data flow node referring to a Mongoose query object.
434+
*/
435+
private DataFlow::SourceNode getAQuery() { result = getAQuery(DataFlow::TypeTracker::end()) }
436+
432437
/**
433438
* An expression passed to `mongoose.createConnection` to supply credentials.
434439
*/
@@ -460,9 +465,43 @@ private module Mongoose {
460465
this = any(QueryFromConstructor c).getArgument(2).asExpr()
461466
or
462467
exists(string method, int n | QueryMethodSignatures::interpretsArgumentAsQuery(method, n) |
463-
this =
464-
getAQuery(DataFlow::TypeTracker::end()).getAMethodCall(method).getArgument(n).asExpr()
468+
this = getAQuery().getAMethodCall(method).getArgument(n).asExpr()
465469
)
466470
}
467471
}
472+
473+
/**
474+
* An evaluation of a MongoDB query.
475+
*/
476+
class MongoDBQueryEvaluation extends DatabaseAccess {
477+
DataFlow::MethodCallNode mcn;
478+
479+
MongoDBQueryEvaluation() {
480+
this = mcn and
481+
(
482+
exists(Model m, string method |
483+
ModelMethodSignatures::returnsQuery(method) and
484+
mcn = m.ref().getAMethodCall(method) and
485+
// callback provided to a Model method call
486+
exists(mcn.getCallback(mcn.getNumArgument() - 1))
487+
)
488+
or
489+
getAQuery().getAMethodCall() = mcn and
490+
(
491+
// explicit execution using a Query method call
492+
exists(string executor | executor = "exec" or executor = "then" or executor = "catch" |
493+
mcn.getMethodName() = executor
494+
)
495+
or
496+
// callback provided to a Query method call
497+
exists(mcn.getCallback(mcn.getNumArgument() - 1))
498+
)
499+
)
500+
}
501+
502+
override DataFlow::Node getAQueryArgument() {
503+
// NB: this does not account for all of the chained calls leading to this execution
504+
mcn.getAnArgument().asExpr().(MongoDBQueryPart).flow() = result
505+
}
506+
}
468507
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
| mongodb.js:18:7:18:21 | doc.find(query) |
2+
| mongodb.js:21:7:21:48 | doc.fin ... itle }) |
3+
| mongodb.js:24:7:24:53 | doc.fin ... r(1) }) |
4+
| mongodb.js:29:9:29:34 | doc.fin ... itle }) |
5+
| mongodb.js:32:9:32:46 | doc.fin ... tle) }) |
6+
| mongodb.js:43:7:43:21 | doc.find(query) |
7+
| mongodb.js:54:7:54:21 | doc.find(query) |
8+
| mongodb.js:65:3:65:17 | doc.find(query) |
9+
| mongodb.js:73:5:77:27 | client\\n ... tag }) |
10+
| mongodb.js:81:3:85:25 | importe ... tag }) |
11+
| mongodb_bodySafe.js:18:7:18:21 | doc.find(query) |
12+
| mongodb_bodySafe.js:29:7:29:21 | doc.find(query) |
13+
| mongoose.js:63:2:63:34 | Documen ... then(X) |
14+
| mongoose.js:65:2:65:51 | Documen ... on(){}) |
15+
| mongoose.js:67:2:68:27 | new Mon ... on(){}) |
16+
| mongoose.js:71:2:77:9 | Documen ... .exec() |
17+
| socketio.js:11:5:11:54 | db.run( ... ndle}`) |
18+
| tst2.js:7:3:7:62 | sql.que ... ms.id}` |
19+
| tst2.js:9:3:9:85 | new sql ... + "'") |
20+
| tst3.js:10:3:12:4 | pool.qu ... ts\\n }) |
21+
| tst3.js:17:3:19:4 | pool.qu ... ts\\n }) |
22+
| tst4.js:8:3:8:67 | db.get( ... + '"') |
23+
| tst.js:10:3:10:65 | db.get( ... + '"') |
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import javascript
2+
3+
select any(DatabaseAccess a)

0 commit comments

Comments
 (0)