Skip to content

Commit dbeb216

Browse files
committed
JS: make use of TypeScript types for mongoose Model and Query
1 parent 0c46e4d commit dbeb216

4 files changed

Lines changed: 49 additions & 5 deletions

File tree

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,10 @@ private module Mongoose {
213213
* A Mongoose collection object.
214214
*/
215215
class Model extends DataFlow::SourceNode {
216-
Model() { this = getAMongooseInstance().getAMemberCall("model") }
216+
Model() {
217+
this = getAMongooseInstance().getAMemberCall("model") or
218+
this.hasUnderlyingType("mongoose", "Model")
219+
}
217220

218221
private DataFlow::SourceNode ref(DataFlow::TypeTracker t) {
219222
result = this and
@@ -417,7 +420,8 @@ private module Mongoose {
417420
private DataFlow::SourceNode getAQuery(DataFlow::TypeTracker t) {
418421
(
419422
result instanceof QueryFromConstructor or
420-
result instanceof QueryFromModel
423+
result instanceof QueryFromModel or
424+
result.hasUnderlyingType("mongoose", "Query")
421425
) and
422426
t.start()
423427
or

javascript/ql/test/query-tests/Security/CWE-089/typed/SqlInjection.expected

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,17 @@ nodes
77
| typedClient.ts:14:24:14:32 | { id: v } |
88
| typedClient.ts:14:24:14:32 | { id: v } |
99
| typedClient.ts:14:30:14:30 | v |
10+
| typedClient.ts:21:7:21:32 | v |
11+
| typedClient.ts:21:11:21:32 | JSON.pa ... body.x) |
12+
| typedClient.ts:21:22:21:29 | req.body |
13+
| typedClient.ts:21:22:21:29 | req.body |
14+
| typedClient.ts:21:22:21:31 | req.body.x |
15+
| typedClient.ts:22:27:22:35 | { id: v } |
16+
| typedClient.ts:22:27:22:35 | { id: v } |
17+
| typedClient.ts:22:33:22:33 | v |
18+
| typedClient.ts:23:27:23:35 | { id: v } |
19+
| typedClient.ts:23:27:23:35 | { id: v } |
20+
| typedClient.ts:23:33:23:33 | v |
1021
edges
1122
| typedClient.ts:13:7:13:32 | v | typedClient.ts:14:30:14:30 | v |
1223
| typedClient.ts:13:11:13:32 | JSON.pa ... body.x) | typedClient.ts:13:7:13:32 | v |
@@ -15,5 +26,17 @@ edges
1526
| typedClient.ts:13:22:13:31 | req.body.x | typedClient.ts:13:11:13:32 | JSON.pa ... body.x) |
1627
| typedClient.ts:14:30:14:30 | v | typedClient.ts:14:24:14:32 | { id: v } |
1728
| typedClient.ts:14:30:14:30 | v | typedClient.ts:14:24:14:32 | { id: v } |
29+
| typedClient.ts:21:7:21:32 | v | typedClient.ts:22:33:22:33 | v |
30+
| typedClient.ts:21:7:21:32 | v | typedClient.ts:23:33:23:33 | v |
31+
| typedClient.ts:21:11:21:32 | JSON.pa ... body.x) | typedClient.ts:21:7:21:32 | v |
32+
| typedClient.ts:21:22:21:29 | req.body | typedClient.ts:21:22:21:31 | req.body.x |
33+
| typedClient.ts:21:22:21:29 | req.body | typedClient.ts:21:22:21:31 | req.body.x |
34+
| typedClient.ts:21:22:21:31 | req.body.x | typedClient.ts:21:11:21:32 | JSON.pa ... body.x) |
35+
| typedClient.ts:22:33:22:33 | v | typedClient.ts:22:27:22:35 | { id: v } |
36+
| typedClient.ts:22:33:22:33 | v | typedClient.ts:22:27:22:35 | { id: v } |
37+
| typedClient.ts:23:33:23:33 | v | typedClient.ts:23:27:23:35 | { id: v } |
38+
| typedClient.ts:23:33:23:33 | v | typedClient.ts:23:27:23:35 | { id: v } |
1839
#select
1940
| typedClient.ts:14:24:14:32 | { id: v } | typedClient.ts:13:22:13:29 | req.body | typedClient.ts:14:24:14:32 | { id: v } | This query depends on $@. | typedClient.ts:13:22:13:29 | req.body | a user-provided value |
41+
| typedClient.ts:22:27:22:35 | { id: v } | typedClient.ts:21:22:21:29 | req.body | typedClient.ts:22:27:22:35 | { id: v } | This query depends on $@. | typedClient.ts:21:22:21:29 | req.body | a user-provided value |
42+
| typedClient.ts:23:27:23:35 | { id: v } | typedClient.ts:21:22:21:29 | req.body | typedClient.ts:23:27:23:35 | { id: v } | This query depends on $@. | typedClient.ts:21:22:21:29 | req.body | a user-provided value |

javascript/ql/test/query-tests/Security/CWE-089/typed/shim.d.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,11 @@ declare module "mongodb" {
33
find(query: any): any;
44
}
55
}
6+
declare module "mongoose" {
7+
interface Model {
8+
find(query: any): any;
9+
}
10+
interface Query {
11+
find(query: any): any;
12+
}
13+
}
Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,24 @@
11
import * as mongodb from "mongodb";
22

3-
const express = require('express') as any;
4-
const bodyParser = require('body-parser') as any;
3+
const express = require("express") as any;
4+
const bodyParser = require("body-parser") as any;
55

66
declare function getCollection(): mongodb.Collection;
77

88
let app = express();
99

1010
app.use(bodyParser.json());
1111

12-
app.post('/find', (req, res) => {
12+
app.post("/find", (req, res) => {
1313
let v = JSON.parse(req.body.x);
1414
getCollection().find({ id: v }); // NOT OK
1515
});
16+
17+
import * as mongoose from "mongoose";
18+
declare function getMongooseModel(): mongoose.Model;
19+
declare function getMongooseQuery(): mongoose.Query;
20+
app.post("/find", (req, res) => {
21+
let v = JSON.parse(req.body.x);
22+
getMongooseModel().find({ id: v }); // NOT OK
23+
getMongooseQuery().find({ id: v }); // NOT OK
24+
});

0 commit comments

Comments
 (0)