Skip to content

Commit ea446f2

Browse files
committed
JS: Use type info in mongodb/mongoose model
1 parent 8e397ad commit ea446f2

File tree

5 files changed

+45
-0
lines changed

5 files changed

+45
-0
lines changed

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,18 @@ private module MongoDB {
7777
}
7878
}
7979

80+
/**
81+
* A collection based on the type `mongodb.Collection`.
82+
*
83+
* Note that this also covers `mongoose` models since they are subtypes
84+
* of `mongodb.Collection`.
85+
*/
86+
private class CollectionFromType extends Collection {
87+
CollectionFromType() {
88+
hasUnderlyingType("mongodb", "Collection")
89+
}
90+
}
91+
8092
/** Gets a data flow node referring to a MongoDB collection. */
8193
private DataFlow::SourceNode getACollection(DataFlow::TypeTracker t) {
8294
t.start() and

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ nodes
6363
| tst4.js:8:46:8:60 | $routeParams.id |
6464
| tst.js:10:10:10:64 | 'SELECT ... d + '"' |
6565
| tst.js:10:46:10:58 | req.params.id |
66+
| typedClient.ts:13:7:13:32 | v |
67+
| typedClient.ts:13:11:13:32 | JSON.pa ... body.x) |
68+
| typedClient.ts:13:22:13:29 | req.body |
69+
| typedClient.ts:13:22:13:31 | req.body.x |
70+
| typedClient.ts:14:24:14:32 | { id: v } |
71+
| typedClient.ts:14:30:14:30 | v |
6672
edges
6773
| mongodb.js:12:11:12:20 | query | mongodb.js:14:59:14:58 | query |
6874
| mongodb.js:12:11:12:20 | query | mongodb.js:18:16:18:20 | query |
@@ -156,6 +162,11 @@ edges
156162
| tst.js:10:10:10:58 | 'SELECT ... rams.id | tst.js:10:10:10:64 | 'SELECT ... d + '"' |
157163
| tst.js:10:46:10:58 | req.params.id | tst.js:10:10:10:58 | 'SELECT ... rams.id |
158164
| tst.js:10:46:10:58 | req.params.id | tst.js:10:10:10:64 | 'SELECT ... d + '"' |
165+
| typedClient.ts:13:7:13:32 | v | typedClient.ts:14:30:14:30 | v |
166+
| typedClient.ts:13:11:13:32 | JSON.pa ... body.x) | typedClient.ts:13:7:13:32 | v |
167+
| typedClient.ts:13:22:13:29 | req.body | typedClient.ts:13:22:13:31 | req.body.x |
168+
| typedClient.ts:13:22:13:31 | req.body.x | typedClient.ts:13:11:13:32 | JSON.pa ... body.x) |
169+
| typedClient.ts:14:30:14:30 | v | typedClient.ts:14:24:14:32 | { id: v } |
159170
#select
160171
| 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 |
161172
| 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 |
@@ -182,3 +193,4 @@ edges
182193
| tst3.js:10:14:10:19 | query1 | tst3.js:9:16:9:34 | req.params.category | tst3.js:10:14:10:19 | query1 | This query depends on $@. | tst3.js:9:16:9:34 | req.params.category | a user-provided value |
183194
| tst4.js:8:10:8:66 | 'SELECT ... d + '"' | tst4.js:8:46:8:60 | $routeParams.id | tst4.js:8:10:8:66 | 'SELECT ... d + '"' | This query depends on $@. | tst4.js:8:46:8:60 | $routeParams.id | a user-provided value |
184195
| 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 + '"' | This query depends on $@. | tst.js:10:46:10:58 | req.params.id | a user-provided value |
196+
| 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 |
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
declare module "mongodb" {
2+
interface Collection {
3+
find(query: any): any;
4+
}
5+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"include": ["."]}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import * as mongodb from "mongodb";
2+
3+
import express from 'express';
4+
import bodyParser from 'body-parser';
5+
6+
declare function getCollection(): mongodb.Collection;
7+
8+
let app = express();
9+
10+
app.use(bodyParser.json());
11+
12+
app.post('/find', (req, res) => {
13+
let v = JSON.parse(req.body.x);
14+
getCollection().find({ id: v }); // NOT OK
15+
});

0 commit comments

Comments
 (0)