JS: model marsdb and minimongo

This commit is contained in:
Esben Sparre Andreasen
2020-05-12 19:24:17 +02:00
parent f5e491caf0
commit 20cf04442c
8 changed files with 214 additions and 0 deletions

View File

@@ -713,3 +713,101 @@ private module Mongoose {
}
}
}
/**
* Provides classes modeling the Minimongo library.
*/
private module Minimongo {
/**
* Gets an expression that may refer to a Minimongo database.
*/
private DataFlow::SourceNode getADb(DataFlow::TypeTracker t) {
t.start() and
// new (require('minimongo')[DBKINDNAME])()
result = DataFlow::moduleImport("minimongo").getAPropertyRead().getAnInvocation()
or
exists(DataFlow::TypeTracker t2 | result = getADb(t2).track(t2, t))
}
/** Gets a data flow node referring to a Minimongo collection. */
private DataFlow::SourceNode getACollection(DataFlow::TypeTracker t) {
t.start() and
// db[COLLECTIONNAME]
result = getADb(DataFlow::TypeTracker::end()).getAPropertyRead()
or
exists(DataFlow::TypeTracker t2 | result = getACollection(t2).track(t2, t))
}
module CollectionMethodSignatures {
predicate interpretsArgumentAsQuery(string m, int queryArgIdx) {
// implements most of the MongoDB interface
MongoDB::CollectionMethodSignatures::interpretsArgumentAsQuery(m, queryArgIdx)
}
}
/** A call to a Minimongo query method. */
private class QueryCall extends DatabaseAccess, DataFlow::MethodCallNode {
int queryArgIdx;
QueryCall() {
exists(string m | this = getACollection(DataFlow::TypeTracker::end()).getAMethodCall(m) |
CollectionMethodSignatures::interpretsArgumentAsQuery(m, queryArgIdx)
)
}
override DataFlow::Node getAQueryArgument() { result = getArgument(queryArgIdx) }
}
/**
* An expression that is interpreted as a Minimongo query.
*/
class Query extends NoSQL::Query {
Query() { this = any(QueryCall qc).getAQueryArgument().asExpr() }
}
}
/**
* Provides classes modeling the MarsDB library.
*/
private module MarsDB {
/**
* Gets an expression that may refer to a MarsDB database.
*/
private DataFlow::SourceNode getADb(DataFlow::TypeTracker t) {
t.start() and
// Collection = require('marsdb')
result = DataFlow::moduleImport("marsdb")
or
exists(DataFlow::TypeTracker t2 | result = getADb(t2).track(t2, t))
}
/** Gets a data flow node referring to a MarsDB collection. */
private DataFlow::SourceNode getACollection(DataFlow::TypeTracker t) {
t.start() and
// new Collection(...)
result = getADb(DataFlow::TypeTracker::end()).getAPropertyRead("Collection").getAnInvocation()
or
exists(DataFlow::TypeTracker t2 | result = getACollection(t2).track(t2, t))
}
/** A call to a MarsDB query method. */
private class QueryCall extends DatabaseAccess, DataFlow::MethodCallNode {
int queryArgIdx;
QueryCall() {
exists(string m | this = getACollection(DataFlow::TypeTracker::end()).getAMethodCall(m) |
// implements parts of the Minimongo interface
Minimongo::CollectionMethodSignatures::interpretsArgumentAsQuery(m, queryArgIdx)
)
}
override DataFlow::Node getAQueryArgument() { result = getArgument(queryArgIdx) }
}
/**
* An expression that is interpreted as a MarsDB query.
*/
class Query extends NoSQL::Query {
Query() { this = any(QueryCall qc).getAQueryArgument().asExpr() }
}
}