Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 61b4ffe

Browse files
committed
add remote flow from the Formidable library
1 parent a03f4ed commit 61b4ffe

3 files changed

Lines changed: 62 additions & 1 deletion

File tree

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

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import javascript
77
/**
88
* Classes and predicate modelling the `Busboy` library.
99
*/
10-
module Busboy {
10+
private module Busboy {
1111
/**
1212
* A `Busboy` instance that has request data flowing into it.
1313
*/
@@ -28,3 +28,25 @@ module Busboy {
2828
override string getSourceType() { result = "Busbuy parsed user value" }
2929
}
3030
}
31+
32+
/**
33+
* A source of remote flow from the `Formidable` library parsing a HTTP request.
34+
*/
35+
private class FormidableRemoteFlow extends RemoteFlowSource {
36+
FormidableRemoteFlow() {
37+
exists(DataFlow::CallNode parse, DataFlow::InvokeNode formidable |
38+
formidable = DataFlow::moduleImport("formidable").getACall()
39+
or
40+
formidable = DataFlow::moduleMember("formidable", "formidable").getACall()
41+
or
42+
formidable =
43+
DataFlow::moduleMember("formidable", ["IncomingForm", "Formidable"]).getAnInstantiation()
44+
|
45+
parse = formidable.getAMemberCall("parse") and
46+
parse.getArgument(0).asExpr() instanceof HTTP::RequestExpr and
47+
this = parse.getABoundCallbackParameter(1, any(int i | i > 0))
48+
)
49+
}
50+
51+
override string getSourceType() { result = "Formidable parsed user value" }
52+
}

javascript/ql/test/query-tests/Security/CWE-078/CommandInjection.expected

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,18 @@ nodes
105105
| form-parsers.js:25:10:25:28 | "touch " + filename |
106106
| form-parsers.js:25:10:25:28 | "touch " + filename |
107107
| form-parsers.js:25:21:25:28 | filename |
108+
| form-parsers.js:35:25:35:30 | fields |
109+
| form-parsers.js:35:25:35:30 | fields |
110+
| form-parsers.js:36:10:36:31 | "touch ... ds.name |
111+
| form-parsers.js:36:10:36:31 | "touch ... ds.name |
112+
| form-parsers.js:36:21:36:26 | fields |
113+
| form-parsers.js:36:21:36:31 | fields.name |
114+
| form-parsers.js:40:26:40:31 | fields |
115+
| form-parsers.js:40:26:40:31 | fields |
116+
| form-parsers.js:41:10:41:31 | "touch ... ds.name |
117+
| form-parsers.js:41:10:41:31 | "touch ... ds.name |
118+
| form-parsers.js:41:21:41:26 | fields |
119+
| form-parsers.js:41:21:41:31 | fields.name |
108120
| lib/subLib/index.js:7:32:7:35 | name |
109121
| lib/subLib/index.js:8:10:8:25 | "rm -rf " + name |
110122
| lib/subLib/index.js:8:10:8:25 | "rm -rf " + name |
@@ -253,6 +265,16 @@ edges
253265
| form-parsers.js:24:48:24:55 | filename | form-parsers.js:25:21:25:28 | filename |
254266
| form-parsers.js:25:21:25:28 | filename | form-parsers.js:25:10:25:28 | "touch " + filename |
255267
| form-parsers.js:25:21:25:28 | filename | form-parsers.js:25:10:25:28 | "touch " + filename |
268+
| form-parsers.js:35:25:35:30 | fields | form-parsers.js:36:21:36:26 | fields |
269+
| form-parsers.js:35:25:35:30 | fields | form-parsers.js:36:21:36:26 | fields |
270+
| form-parsers.js:36:21:36:26 | fields | form-parsers.js:36:21:36:31 | fields.name |
271+
| form-parsers.js:36:21:36:31 | fields.name | form-parsers.js:36:10:36:31 | "touch ... ds.name |
272+
| form-parsers.js:36:21:36:31 | fields.name | form-parsers.js:36:10:36:31 | "touch ... ds.name |
273+
| form-parsers.js:40:26:40:31 | fields | form-parsers.js:41:21:41:26 | fields |
274+
| form-parsers.js:40:26:40:31 | fields | form-parsers.js:41:21:41:26 | fields |
275+
| form-parsers.js:41:21:41:26 | fields | form-parsers.js:41:21:41:31 | fields.name |
276+
| form-parsers.js:41:21:41:31 | fields.name | form-parsers.js:41:10:41:31 | "touch ... ds.name |
277+
| form-parsers.js:41:21:41:31 | fields.name | form-parsers.js:41:10:41:31 | "touch ... ds.name |
256278
| lib/subLib/index.js:7:32:7:35 | name | lib/subLib/index.js:8:22:8:25 | name |
257279
| lib/subLib/index.js:8:22:8:25 | name | lib/subLib/index.js:8:10:8:25 | "rm -rf " + name |
258280
| lib/subLib/index.js:8:22:8:25 | name | lib/subLib/index.js:8:10:8:25 | "rm -rf " + name |
@@ -327,6 +349,8 @@ edges
327349
| form-parsers.js:9:8:9:39 | "touch ... nalname | form-parsers.js:9:19:9:26 | req.file | form-parsers.js:9:8:9:39 | "touch ... nalname | This command depends on $@. | form-parsers.js:9:19:9:26 | req.file | a user-provided value |
328350
| form-parsers.js:14:10:14:37 | "touch ... nalname | form-parsers.js:13:3:13:11 | req.files | form-parsers.js:14:10:14:37 | "touch ... nalname | This command depends on $@. | form-parsers.js:13:3:13:11 | req.files | a user-provided value |
329351
| form-parsers.js:25:10:25:28 | "touch " + filename | form-parsers.js:24:48:24:55 | filename | form-parsers.js:25:10:25:28 | "touch " + filename | This command depends on $@. | form-parsers.js:24:48:24:55 | filename | a user-provided value |
352+
| form-parsers.js:36:10:36:31 | "touch ... ds.name | form-parsers.js:35:25:35:30 | fields | form-parsers.js:36:10:36:31 | "touch ... ds.name | This command depends on $@. | form-parsers.js:35:25:35:30 | fields | a user-provided value |
353+
| form-parsers.js:41:10:41:31 | "touch ... ds.name | form-parsers.js:40:26:40:31 | fields | form-parsers.js:41:10:41:31 | "touch ... ds.name | This command depends on $@. | form-parsers.js:40:26:40:31 | fields | a user-provided value |
330354
| lib/subLib/index.js:8:10:8:25 | "rm -rf " + name | child_process-test.js:85:37:85:54 | req.query.fileName | lib/subLib/index.js:8:10:8:25 | "rm -rf " + name | This command depends on $@. | child_process-test.js:85:37:85:54 | req.query.fileName | a user-provided value |
331355
| other.js:7:33:7:35 | cmd | other.js:5:25:5:31 | req.url | other.js:7:33:7:35 | cmd | This command depends on $@. | other.js:5:25:5:31 | req.url | a user-provided value |
332356
| other.js:8:28:8:30 | cmd | other.js:5:25:5:31 | req.url | other.js:8:28:8:30 | cmd | This command depends on $@. | other.js:5:25:5:31 | req.url | a user-provided value |

javascript/ql/test/query-tests/Security/CWE-078/form-parsers.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,18 @@ http.createServer(function (req, res) {
2626
});
2727
req.pipe(busboy);
2828
}).listen(8000);
29+
30+
31+
const formidable = require('formidable');
32+
app.post('/api/upload', (req, res, next) => {
33+
let form = formidable({ multiples: true });
34+
35+
form.parse(req, (err, fields, files) => {
36+
exec("touch " + fields.name); // NOT OK
37+
});
38+
39+
let form2 = new formidable.IncomingForm();
40+
form2.parse(req, (err, fields, files) => {
41+
exec("touch " + fields.name); // NOT OK
42+
});
43+
});

0 commit comments

Comments
 (0)