add taint through the qs library

This commit is contained in:
Erik Krogh Kristensen
2021-07-14 16:56:51 +02:00
parent e0a123cbd0
commit 193ddfc771
4 changed files with 127 additions and 0 deletions

View File

@@ -0,0 +1,4 @@
lgtm,codescanning
* The security queries now track taint through more query string parsers.
Affected packages are
[qs](https://npmjs.com/package/qs)

View File

@@ -292,6 +292,20 @@ module querystring {
}
}
/**
* A taint step through a call to [qs](https://npmjs.com/package/qs)
*/
private class QsStep extends TaintTracking::SharedTaintStep {
override predicate uriStep(DataFlow::Node pred, DataFlow::Node succ) {
exists(API::CallNode call |
call = API::moduleImport("qs").getMember(["parse", "stringify"]).getACall()
|
pred = call.getArgument(0) and
succ = call
)
}
}
/**
* Provides steps for the `goog.Uri` class in the closure library.
*/

View File

@@ -1285,6 +1285,44 @@ nodes
| TaintedPath.js:195:50:195:53 | path |
| TaintedPath.js:195:50:195:53 | path |
| TaintedPath.js:195:50:195:53 | path |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:38:201:44 | req.url |
| TaintedPath.js:201:38:201:44 | req.url |
| TaintedPath.js:201:38:201:44 | req.url |
| TaintedPath.js:201:38:201:44 | req.url |
| TaintedPath.js:201:38:201:44 | req.url |
| normalizedPaths.js:11:7:11:27 | path |
| normalizedPaths.js:11:7:11:27 | path |
| normalizedPaths.js:11:7:11:27 | path |
@@ -5506,6 +5544,70 @@ edges
| TaintedPath.js:195:50:195:53 | path | TaintedPath.js:195:29:195:54 | pathMod ... e(path) |
| TaintedPath.js:195:50:195:53 | path | TaintedPath.js:195:29:195:54 | pathMod ... e(path) |
| TaintedPath.js:195:50:195:53 | path | TaintedPath.js:195:29:195:54 | pathMod ... e(path) |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) | TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) | TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) | TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) | TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) | TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) | TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) | TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) | TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) | TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) | TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) | TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) | TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) | TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) | TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) | TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) | TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) | TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) | TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) | TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) | TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) | TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) | TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) | TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) | TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) | TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) | TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) | TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) | TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) | TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) | TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) | TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:29:201:45 | qs.parse(req.url) | TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo |
| TaintedPath.js:201:38:201:44 | req.url | TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:38:201:44 | req.url | TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:38:201:44 | req.url | TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:38:201:44 | req.url | TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:38:201:44 | req.url | TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:38:201:44 | req.url | TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:38:201:44 | req.url | TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:38:201:44 | req.url | TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:38:201:44 | req.url | TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:38:201:44 | req.url | TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:38:201:44 | req.url | TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:38:201:44 | req.url | TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:38:201:44 | req.url | TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:38:201:44 | req.url | TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:38:201:44 | req.url | TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:38:201:44 | req.url | TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:38:201:44 | req.url | TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:38:201:44 | req.url | TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:38:201:44 | req.url | TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:38:201:44 | req.url | TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:38:201:44 | req.url | TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:38:201:44 | req.url | TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:38:201:44 | req.url | TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:38:201:44 | req.url | TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:38:201:44 | req.url | TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:38:201:44 | req.url | TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:38:201:44 | req.url | TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:38:201:44 | req.url | TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:38:201:44 | req.url | TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:38:201:44 | req.url | TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:38:201:44 | req.url | TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| TaintedPath.js:201:38:201:44 | req.url | TaintedPath.js:201:29:201:45 | qs.parse(req.url) |
| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:13:19:13:22 | path |
| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:13:19:13:22 | path |
| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:13:19:13:22 | path |
@@ -8627,6 +8729,7 @@ edges
| TaintedPath.js:179:29:179:57 | path.re ... /g, '') | TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:179:29:179:57 | path.re ... /g, '') | This path depends on $@. | TaintedPath.js:166:24:166:30 | req.url | a user-provided value |
| TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:194:29:194:73 | "prefix ... +/, '') | This path depends on $@. | TaintedPath.js:166:24:166:30 | req.url | a user-provided value |
| TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | TaintedPath.js:166:24:166:30 | req.url | TaintedPath.js:195:29:195:84 | pathMod ... +/, '') | This path depends on $@. | TaintedPath.js:166:24:166:30 | req.url | a user-provided value |
| TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo | TaintedPath.js:201:38:201:44 | req.url | TaintedPath.js:201:29:201:49 | qs.pars ... rl).foo | This path depends on $@. | TaintedPath.js:201:38:201:44 | req.url | a user-provided value |
| normalizedPaths.js:13:19:13:22 | path | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:13:19:13:22 | path | This path depends on $@. | normalizedPaths.js:11:14:11:27 | req.query.path | a user-provided value |
| normalizedPaths.js:14:19:14:29 | './' + path | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:14:19:14:29 | './' + path | This path depends on $@. | normalizedPaths.js:11:14:11:27 | req.query.path | a user-provided value |
| normalizedPaths.js:15:19:15:38 | path + '/index.html' | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:15:19:15:38 | path + '/index.html' | This path depends on $@. | normalizedPaths.js:11:14:11:27 | req.query.path | a user-provided value |

View File

@@ -193,4 +193,10 @@ var server = http.createServer(function(req, res) {
res.write(fs.readFileSync("prefix" + path.replace(/^(\.\.[\/\\])+/, ''))); // NOT OK - not normalized
res.write(fs.readFileSync(pathModule.normalize(path).replace(/^(\.\.[\/\\])+/, ''))); // NOT OK (can be absolute)
});
var server = http.createServer(function(req, res) {
// tests for a few more uri-libraries
const qs = require("qs");
res.write(fs.readFileSync(qs.parse(req.url).foo)); // NOT OK
});