зеркало из https://github.com/github/codeql.git
Коммит
6d80445f24
|
@ -463,6 +463,26 @@ module Express {
|
|||
override RequestSource src;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a reference to the "query" object from a request-object originating from route-handler `rh`.
|
||||
*/
|
||||
DataFlow::SourceNode getAQueryObjectReference(DataFlow::TypeTracker t, RouteHandler rh) {
|
||||
t.startInProp("query") and
|
||||
result = rh.getARequestSource()
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = getAQueryObjectReference(t2, rh).track(t2, t))
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a reference to the "params" object from a request-object originating from route-handler `rh`.
|
||||
*/
|
||||
DataFlow::SourceNode getAParamsObjectReference(DataFlow::TypeTracker t, RouteHandler rh) {
|
||||
t.startInProp("params") and
|
||||
result = rh.getARequestSource()
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = getAParamsObjectReference(t2, rh).track(t2, t))
|
||||
}
|
||||
|
||||
/**
|
||||
* An access to a user-controlled Express request input.
|
||||
*/
|
||||
|
@ -471,13 +491,14 @@ module Express {
|
|||
string kind;
|
||||
|
||||
RequestInputAccess() {
|
||||
kind = "parameter" and
|
||||
this =
|
||||
[getAQueryObjectReference(DataFlow::TypeTracker::end(), rh),
|
||||
getAParamsObjectReference(DataFlow::TypeTracker::end(), rh)].getAPropertyRead()
|
||||
or
|
||||
exists(DataFlow::SourceNode request | request = rh.getARequestSource().ref() |
|
||||
kind = "parameter" and
|
||||
(
|
||||
this = request.getAMethodCall("param")
|
||||
or
|
||||
this = request.getAPropertyRead(["params", "query"]).getAPropertyRead()
|
||||
)
|
||||
this = request.getAMethodCall("param")
|
||||
or
|
||||
// `req.originalUrl`
|
||||
kind = "url" and
|
||||
|
@ -518,13 +539,11 @@ module Express {
|
|||
kind = "parameter" and
|
||||
exists(DataFlow::Node request | request = DataFlow::valueNode(rh.getARequestExpr()) |
|
||||
this.(DataFlow::MethodCallNode).calls(request, "param")
|
||||
or
|
||||
exists(DataFlow::PropRead base |
|
||||
// `req.query.name`
|
||||
base.accesses(request, "query") and
|
||||
this = base.getAPropertyReference(_)
|
||||
)
|
||||
)
|
||||
or
|
||||
// `req.query.name`
|
||||
kind = "parameter" and
|
||||
this = getAQueryObjectReference(DataFlow::TypeTracker::end(), rh).getAPropertyRead()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,10 @@ nodes
|
|||
| ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id |
|
||||
| ReflectedXss.js:8:33:8:45 | req.params.id |
|
||||
| ReflectedXss.js:8:33:8:45 | req.params.id |
|
||||
| ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id |
|
||||
| ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id |
|
||||
| ReflectedXss.js:17:31:17:39 | params.id |
|
||||
| ReflectedXss.js:17:31:17:39 | params.id |
|
||||
| ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id |
|
||||
| ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id |
|
||||
| ReflectedXssContentTypes.js:10:24:10:36 | req.params.id |
|
||||
|
@ -95,6 +99,10 @@ edges
|
|||
| ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id |
|
||||
| ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id |
|
||||
| ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id |
|
||||
| ReflectedXss.js:17:31:17:39 | params.id | ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id |
|
||||
| ReflectedXss.js:17:31:17:39 | params.id | ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id |
|
||||
| ReflectedXss.js:17:31:17:39 | params.id | ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id |
|
||||
| ReflectedXss.js:17:31:17:39 | params.id | ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id |
|
||||
| ReflectedXssContentTypes.js:10:24:10:36 | req.params.id | ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id |
|
||||
| ReflectedXssContentTypes.js:10:24:10:36 | req.params.id | ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id |
|
||||
| ReflectedXssContentTypes.js:10:24:10:36 | req.params.id | ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id |
|
||||
|
@ -173,6 +181,7 @@ edges
|
|||
| tst2.js:14:9:14:9 | p | tst2.js:14:7:14:24 | p |
|
||||
#select
|
||||
| ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:8:33:8:45 | req.params.id | user-provided value |
|
||||
| ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id | ReflectedXss.js:17:31:17:39 | params.id | ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:17:31:17:39 | params.id | user-provided value |
|
||||
| ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id | ReflectedXssContentTypes.js:10:24:10:36 | req.params.id | ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id | Cross-site scripting vulnerability due to $@. | ReflectedXssContentTypes.js:10:24:10:36 | req.params.id | user-provided value |
|
||||
| ReflectedXssContentTypes.js:20:14:20:36 | "FOO: " ... rams.id | ReflectedXssContentTypes.js:20:24:20:36 | req.params.id | ReflectedXssContentTypes.js:20:14:20:36 | "FOO: " ... rams.id | Cross-site scripting vulnerability due to $@. | ReflectedXssContentTypes.js:20:24:20:36 | req.params.id | user-provided value |
|
||||
| ReflectedXssContentTypes.js:39:13:39:35 | "FOO: " ... rams.id | ReflectedXssContentTypes.js:39:23:39:35 | req.params.id | ReflectedXssContentTypes.js:39:13:39:35 | "FOO: " ... rams.id | Cross-site scripting vulnerability due to $@. | ReflectedXssContentTypes.js:39:23:39:35 | req.params.id | user-provided value |
|
||||
|
|
|
@ -3,10 +3,16 @@ var express = require('express');
|
|||
var app = express();
|
||||
|
||||
app.get('/user/:id', function(req, res) {
|
||||
if (!isValidUserId(req.params.id))
|
||||
if (!isValidUserId(req.params.id)) {
|
||||
// BAD: a request parameter is incorporated without validation into the response
|
||||
res.send("Unknown user: " + req.params.id);
|
||||
else
|
||||
moreBadStuff(req.params, res);
|
||||
} else {
|
||||
// TODO: do something exciting
|
||||
;
|
||||
}
|
||||
});
|
||||
|
||||
function moreBadStuff(params, res) {
|
||||
res.send("Unknown user: " + params.id); // NOT OK
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
| ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:8:33:8:45 | req.params.id | user-provided value |
|
||||
| ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:17:31:17:39 | params.id | user-provided value |
|
||||
| ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id | Cross-site scripting vulnerability due to $@. | ReflectedXssContentTypes.js:10:24:10:36 | req.params.id | user-provided value |
|
||||
| ReflectedXssContentTypes.js:20:14:20:36 | "FOO: " ... rams.id | Cross-site scripting vulnerability due to $@. | ReflectedXssContentTypes.js:20:24:20:36 | req.params.id | user-provided value |
|
||||
| ReflectedXssContentTypes.js:39:13:39:35 | "FOO: " ... rams.id | Cross-site scripting vulnerability due to $@. | ReflectedXssContentTypes.js:39:23:39:35 | req.params.id | user-provided value |
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
| mongodb.js:65:3:65:17 | doc.find(query) |
|
||||
| mongodb.js:73:5:77:27 | client\\n ... tag }) |
|
||||
| mongodb.js:81:3:85:25 | importe ... tag }) |
|
||||
| mongodb.js:98:5:98:19 | doc.find(query) |
|
||||
| mongodb.js:112:5:112:19 | doc.find(query) |
|
||||
| mongodb_bodySafe.js:18:7:18:21 | doc.find(query) |
|
||||
| mongodb_bodySafe.js:29:7:29:21 | doc.find(query) |
|
||||
| mongoose.js:63:2:63:34 | Documen ... then(X) |
|
||||
|
|
|
@ -56,6 +56,12 @@ nodes
|
|||
| mongodb.js:85:12:85:24 | { tags: tag } |
|
||||
| mongodb.js:85:12:85:24 | { tags: tag } |
|
||||
| mongodb.js:85:20:85:22 | tag |
|
||||
| mongodb.js:106:9:106:18 | query |
|
||||
| mongodb.js:106:17:106:18 | {} |
|
||||
| mongodb.js:107:17:107:29 | queries.title |
|
||||
| mongodb.js:107:17:107:29 | queries.title |
|
||||
| mongodb.js:112:14:112:18 | query |
|
||||
| mongodb.js:112:14:112:18 | query |
|
||||
| mongodb_bodySafe.js:23:11:23:20 | query |
|
||||
| mongodb_bodySafe.js:23:19:23:20 | {} |
|
||||
| mongodb_bodySafe.js:24:19:24:33 | req.query.title |
|
||||
|
@ -244,6 +250,17 @@ edges
|
|||
| mongodb.js:77:22:77:24 | tag | mongodb.js:77:14:77:26 | { tags: tag } |
|
||||
| mongodb.js:85:20:85:22 | tag | mongodb.js:85:12:85:24 | { tags: tag } |
|
||||
| mongodb.js:85:20:85:22 | tag | mongodb.js:85:12:85:24 | { tags: tag } |
|
||||
| mongodb.js:106:9:106:18 | query | mongodb.js:112:14:112:18 | query |
|
||||
| mongodb.js:106:9:106:18 | query | mongodb.js:112:14:112:18 | query |
|
||||
| mongodb.js:106:17:106:18 | {} | mongodb.js:106:9:106:18 | query |
|
||||
| mongodb.js:107:17:107:29 | queries.title | mongodb.js:106:9:106:18 | query |
|
||||
| mongodb.js:107:17:107:29 | queries.title | mongodb.js:106:9:106:18 | query |
|
||||
| mongodb.js:107:17:107:29 | queries.title | mongodb.js:106:17:106:18 | {} |
|
||||
| mongodb.js:107:17:107:29 | queries.title | mongodb.js:106:17:106:18 | {} |
|
||||
| mongodb.js:107:17:107:29 | queries.title | mongodb.js:112:14:112:18 | query |
|
||||
| mongodb.js:107:17:107:29 | queries.title | mongodb.js:112:14:112:18 | query |
|
||||
| mongodb.js:107:17:107:29 | queries.title | mongodb.js:112:14:112:18 | query |
|
||||
| mongodb.js:107:17:107:29 | queries.title | mongodb.js:112:14:112:18 | query |
|
||||
| mongodb_bodySafe.js:23:11:23:20 | query | mongodb_bodySafe.js:29:16:29:20 | query |
|
||||
| mongodb_bodySafe.js:23:11:23:20 | query | mongodb_bodySafe.js:29:16:29:20 | query |
|
||||
| mongodb_bodySafe.js:23:19:23:20 | {} | mongodb_bodySafe.js:23:11:23:20 | query |
|
||||
|
@ -428,6 +445,7 @@ edges
|
|||
| mongodb.js:65:12:65:16 | query | mongodb.js:60:16:60:30 | req.query.title | mongodb.js:65:12:65:16 | query | This query depends on $@. | mongodb.js:60:16:60:30 | req.query.title | a user-provided value |
|
||||
| mongodb.js:77:14:77:26 | { tags: tag } | mongodb.js:70:13:70:25 | req.query.tag | mongodb.js:77:14:77:26 | { tags: tag } | This query depends on $@. | mongodb.js:70:13:70:25 | req.query.tag | a user-provided value |
|
||||
| mongodb.js:85:12:85:24 | { tags: tag } | mongodb.js:70:13:70:25 | req.query.tag | mongodb.js:85:12:85:24 | { tags: tag } | This query depends on $@. | mongodb.js:70:13:70:25 | req.query.tag | a user-provided value |
|
||||
| mongodb.js:112:14:112:18 | query | mongodb.js:107:17:107:29 | queries.title | mongodb.js:112:14:112:18 | query | This query depends on $@. | mongodb.js:107:17:107:29 | queries.title | a user-provided value |
|
||||
| mongodb_bodySafe.js:29:16:29:20 | query | mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:29:16:29:20 | query | This query depends on $@. | mongodb_bodySafe.js:24:19:24:33 | req.query.title | a user-provided value |
|
||||
| mongoose.js:24:24:24:30 | [query] | mongoose.js:21:19:21:26 | req.body | mongoose.js:24:24:24:30 | [query] | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
|
||||
| mongoose.js:27:20:27:24 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:27:20:27:24 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
|
||||
|
|
|
@ -84,3 +84,31 @@ app.post("/logs/count-by-tag", (req, res) => {
|
|||
// NOT OK: query is tainted by user-provided object value
|
||||
.count({ tags: tag });
|
||||
});
|
||||
|
||||
|
||||
app.get('/:id', (req, res) => {
|
||||
useParams(req.param);
|
||||
});
|
||||
function useParams(params) {
|
||||
let query = { id: params.id };
|
||||
MongoClient.connect('mongodb://localhost:27017/test', (err, db) => {
|
||||
let doc = db.collection('doc');
|
||||
|
||||
// OK: query is tainted, but only by string value
|
||||
doc.find(query);
|
||||
});
|
||||
}
|
||||
|
||||
app.post('/documents/find', (req, res) => {
|
||||
useQuery(req.query);
|
||||
});
|
||||
function useQuery(queries) {
|
||||
const query = {};
|
||||
query.title = queries.title;
|
||||
MongoClient.connect('mongodb://localhost:27017/test', (err, db) => {
|
||||
let doc = db.collection('doc');
|
||||
|
||||
// NOT OK: query is tainted by user-provided object value
|
||||
doc.find(query);
|
||||
});
|
||||
}
|
Загрузка…
Ссылка в новой задаче