mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
JS: model marsdb and minimongo
This commit is contained in:
@@ -6,6 +6,8 @@
|
||||
- [fstream](https://www.npmjs.com/package/fstream)
|
||||
- [jGrowl](https://github.com/stanlemon/jGrowl)
|
||||
- [jQuery](https://jquery.com/)
|
||||
- [marsdb](https://www.npmjs.com/package/marsdb)
|
||||
- [minimongo](https://www.npmjs.com/package/minimongo/)
|
||||
|
||||
## New queries
|
||||
|
||||
|
||||
@@ -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() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
| marsdb-flow-to.js:14:3:14:22 | db.myDoc.find(query) |
|
||||
| marsdb.js:16:3:16:17 | doc.find(query) |
|
||||
| minimongo.js:18:3:18:17 | doc.find(query) |
|
||||
| mongodb.js:18:7:18:21 | doc.find(query) |
|
||||
| mongodb.js:21:7:21:48 | doc.fin ... itle }) |
|
||||
| mongodb.js:24:7:24:53 | doc.fin ... r(1) }) |
|
||||
|
||||
@@ -1,4 +1,25 @@
|
||||
nodes
|
||||
| marsdb-flow-to.js:10:9:10:18 | query |
|
||||
| marsdb-flow-to.js:10:17:10:18 | {} |
|
||||
| marsdb-flow-to.js:11:17:11:24 | req.body |
|
||||
| marsdb-flow-to.js:11:17:11:24 | req.body |
|
||||
| marsdb-flow-to.js:11:17:11:30 | req.body.title |
|
||||
| marsdb-flow-to.js:14:17:14:21 | query |
|
||||
| marsdb-flow-to.js:14:17:14:21 | query |
|
||||
| marsdb.js:12:9:12:18 | query |
|
||||
| marsdb.js:12:17:12:18 | {} |
|
||||
| marsdb.js:13:17:13:24 | req.body |
|
||||
| marsdb.js:13:17:13:24 | req.body |
|
||||
| marsdb.js:13:17:13:30 | req.body.title |
|
||||
| marsdb.js:16:12:16:16 | query |
|
||||
| marsdb.js:16:12:16:16 | query |
|
||||
| minimongo.js:14:9:14:18 | query |
|
||||
| minimongo.js:14:17:14:18 | {} |
|
||||
| minimongo.js:15:17:15:24 | req.body |
|
||||
| minimongo.js:15:17:15:24 | req.body |
|
||||
| minimongo.js:15:17:15:30 | req.body.title |
|
||||
| minimongo.js:18:12:18:16 | query |
|
||||
| minimongo.js:18:12:18:16 | query |
|
||||
| mongodb.js:12:11:12:20 | query |
|
||||
| mongodb.js:12:19:12:20 | {} |
|
||||
| mongodb.js:13:19:13:26 | req.body |
|
||||
@@ -150,6 +171,33 @@ nodes
|
||||
| tst.js:10:46:10:58 | req.params.id |
|
||||
| tst.js:10:46:10:58 | req.params.id |
|
||||
edges
|
||||
| marsdb-flow-to.js:10:9:10:18 | query | marsdb-flow-to.js:14:17:14:21 | query |
|
||||
| marsdb-flow-to.js:10:9:10:18 | query | marsdb-flow-to.js:14:17:14:21 | query |
|
||||
| marsdb-flow-to.js:10:17:10:18 | {} | marsdb-flow-to.js:10:9:10:18 | query |
|
||||
| marsdb-flow-to.js:11:17:11:24 | req.body | marsdb-flow-to.js:11:17:11:30 | req.body.title |
|
||||
| marsdb-flow-to.js:11:17:11:24 | req.body | marsdb-flow-to.js:11:17:11:30 | req.body.title |
|
||||
| marsdb-flow-to.js:11:17:11:30 | req.body.title | marsdb-flow-to.js:10:9:10:18 | query |
|
||||
| marsdb-flow-to.js:11:17:11:30 | req.body.title | marsdb-flow-to.js:10:17:10:18 | {} |
|
||||
| marsdb-flow-to.js:11:17:11:30 | req.body.title | marsdb-flow-to.js:14:17:14:21 | query |
|
||||
| marsdb-flow-to.js:11:17:11:30 | req.body.title | marsdb-flow-to.js:14:17:14:21 | query |
|
||||
| marsdb.js:12:9:12:18 | query | marsdb.js:16:12:16:16 | query |
|
||||
| marsdb.js:12:9:12:18 | query | marsdb.js:16:12:16:16 | query |
|
||||
| marsdb.js:12:17:12:18 | {} | marsdb.js:12:9:12:18 | query |
|
||||
| marsdb.js:13:17:13:24 | req.body | marsdb.js:13:17:13:30 | req.body.title |
|
||||
| marsdb.js:13:17:13:24 | req.body | marsdb.js:13:17:13:30 | req.body.title |
|
||||
| marsdb.js:13:17:13:30 | req.body.title | marsdb.js:12:9:12:18 | query |
|
||||
| marsdb.js:13:17:13:30 | req.body.title | marsdb.js:12:17:12:18 | {} |
|
||||
| marsdb.js:13:17:13:30 | req.body.title | marsdb.js:16:12:16:16 | query |
|
||||
| marsdb.js:13:17:13:30 | req.body.title | marsdb.js:16:12:16:16 | query |
|
||||
| minimongo.js:14:9:14:18 | query | minimongo.js:18:12:18:16 | query |
|
||||
| minimongo.js:14:9:14:18 | query | minimongo.js:18:12:18:16 | query |
|
||||
| minimongo.js:14:17:14:18 | {} | minimongo.js:14:9:14:18 | query |
|
||||
| minimongo.js:15:17:15:24 | req.body | minimongo.js:15:17:15:30 | req.body.title |
|
||||
| minimongo.js:15:17:15:24 | req.body | minimongo.js:15:17:15:30 | req.body.title |
|
||||
| minimongo.js:15:17:15:30 | req.body.title | minimongo.js:14:9:14:18 | query |
|
||||
| minimongo.js:15:17:15:30 | req.body.title | minimongo.js:14:17:14:18 | {} |
|
||||
| minimongo.js:15:17:15:30 | req.body.title | minimongo.js:18:12:18:16 | query |
|
||||
| minimongo.js:15:17:15:30 | req.body.title | minimongo.js:18:12:18:16 | query |
|
||||
| mongodb.js:12:11:12:20 | query | mongodb.js:18:16:18:20 | query |
|
||||
| mongodb.js:12:11:12:20 | query | mongodb.js:18:16:18:20 | query |
|
||||
| mongodb.js:12:19:12:20 | {} | mongodb.js:12:11:12:20 | query |
|
||||
@@ -371,6 +419,9 @@ edges
|
||||
| tst.js:10:46:10:58 | req.params.id | tst.js:10:10:10:64 | 'SELECT ... d + '"' |
|
||||
| tst.js:10:46:10:58 | req.params.id | tst.js:10:10:10:64 | 'SELECT ... d + '"' |
|
||||
#select
|
||||
| marsdb-flow-to.js:14:17:14:21 | query | marsdb-flow-to.js:11:17:11:24 | req.body | marsdb-flow-to.js:14:17:14:21 | query | This query depends on $@. | marsdb-flow-to.js:11:17:11:24 | req.body | a user-provided value |
|
||||
| marsdb.js:16:12:16:16 | query | marsdb.js:13:17:13:24 | req.body | marsdb.js:16:12:16:16 | query | This query depends on $@. | marsdb.js:13:17:13:24 | req.body | a user-provided value |
|
||||
| minimongo.js:18:12:18:16 | query | minimongo.js:15:17:15:24 | req.body | minimongo.js:18:12:18:16 | query | This query depends on $@. | minimongo.js:15:17:15:24 | req.body | a user-provided value |
|
||||
| mongodb.js:18:16:18:20 | query | mongodb.js:13:19:13:26 | req.body | mongodb.js:18:16:18:20 | query | This query depends on $@. | mongodb.js:13:19:13:26 | req.body | a user-provided value |
|
||||
| mongodb.js:32:18:32:45 | { title ... itle) } | mongodb.js:26:19:26:26 | req.body | mongodb.js:32:18:32:45 | { title ... itle) } | This query depends on $@. | mongodb.js:26:19:26:26 | req.body | a user-provided value |
|
||||
| mongodb.js:54:16:54:20 | query | mongodb.js:49:19:49:33 | req.query.title | mongodb.js:54:16:54:20 | query | This query depends on $@. | mongodb.js:49:19:49:33 | req.query.title | a user-provided value |
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
const MarsDB = require("marsdb");
|
||||
|
||||
const myDoc = new MarsDB.Collection("myDoc");
|
||||
|
||||
const db = {
|
||||
myDoc
|
||||
};
|
||||
|
||||
module.exports = db;
|
||||
@@ -0,0 +1,15 @@
|
||||
const express = require("express"),
|
||||
bodyParser = require("body-parser"),
|
||||
db = require('./marsdb-flow-from');
|
||||
|
||||
const app = express();
|
||||
|
||||
app.use(bodyParser.urlencoded({ extended: true }));
|
||||
|
||||
app.post("/documents/find", (req, res) => {
|
||||
const query = {};
|
||||
query.title = req.body.title;
|
||||
|
||||
// NOT OK: query is tainted by user-provided object value
|
||||
db.myDoc.find(query);
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
const express = require("express"),
|
||||
MarsDB = require("marsdb"),
|
||||
bodyParser = require("body-parser");
|
||||
|
||||
let doc = new MarsDB.Collection("myDoc");
|
||||
|
||||
const app = express();
|
||||
|
||||
app.use(bodyParser.urlencoded({ extended: true }));
|
||||
|
||||
app.post("/documents/find", (req, res) => {
|
||||
const query = {};
|
||||
query.title = req.body.title;
|
||||
|
||||
// NOT OK: query is tainted by user-provided object value
|
||||
doc.find(query);
|
||||
});
|
||||
@@ -0,0 +1,19 @@
|
||||
const express = require("express"),
|
||||
minimongo = require("minimongo"),
|
||||
bodyParser = require("body-parser");
|
||||
|
||||
var LocalDb = minimongo.MemoryDb,
|
||||
db = new LocalDb(),
|
||||
doc = db.myDocs;
|
||||
|
||||
const app = express();
|
||||
|
||||
app.use(bodyParser.urlencoded({ extended: true }));
|
||||
|
||||
app.post("/documents/find", (req, res) => {
|
||||
const query = {};
|
||||
query.title = req.body.title;
|
||||
|
||||
// NOT OK: query is tainted by user-provided object value
|
||||
doc.find(query);
|
||||
});
|
||||
Reference in New Issue
Block a user