зеркало из https://github.com/github/codeql.git
Merge pull request #3197 from erik-krogh/NormalPathSanitizer
Approved by asgerf
This commit is contained in:
Коммит
a8098a2b2d
|
@ -206,6 +206,20 @@ module TaintedPath {
|
|||
dstlabel.isNormalized()
|
||||
)
|
||||
or
|
||||
// foo.replace(/(\.\.\/)*/, "") and similar
|
||||
exists(DotDotSlashPrefixRemovingReplace call |
|
||||
src = call.getInput() and
|
||||
dst = call.getOutput()
|
||||
|
|
||||
// the 4 possible combinations of normalized + relative for `srclabel`, and the possible values for `dstlabel` in each case.
|
||||
srclabel.isNonNormalized() and srclabel.isRelative() // raw + relative -> any()
|
||||
or
|
||||
srclabel.isNormalized() and srclabel.isAbsolute() and srclabel = dstlabel // normalized + absolute -> normalized + absolute
|
||||
or
|
||||
srclabel.isNonNormalized() and srclabel.isAbsolute() and dstlabel.isAbsolute() // raw + absolute -> raw/normalized + absolute
|
||||
// normalized + relative -> none()
|
||||
)
|
||||
or
|
||||
// path.join()
|
||||
exists(DataFlow::CallNode join, int n |
|
||||
join = NodeJSLib::Path::moduleMember("join").getACall()
|
||||
|
|
|
@ -225,7 +225,8 @@ module TaintedPath {
|
|||
term.getAMatchedString() = "/" or
|
||||
term.getAMatchedString() = "." or
|
||||
term.getAMatchedString() = ".."
|
||||
)
|
||||
) and
|
||||
not this instanceof DotDotSlashPrefixRemovingReplace
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -239,6 +240,57 @@ module TaintedPath {
|
|||
DataFlow::Node getOutput() { result = output }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call that removes all instances of "../" in the prefix of the string.
|
||||
*/
|
||||
class DotDotSlashPrefixRemovingReplace extends DataFlow::CallNode {
|
||||
DataFlow::Node input;
|
||||
DataFlow::Node output;
|
||||
|
||||
DotDotSlashPrefixRemovingReplace() {
|
||||
this.getCalleeName() = "replace" and
|
||||
input = getReceiver() and
|
||||
output = this and
|
||||
exists(RegExpLiteral literal, RegExpTerm term |
|
||||
getArgument(0).getALocalSource().asExpr() = literal and
|
||||
(term instanceof RegExpStar or term instanceof RegExpPlus) and
|
||||
term.getChild(0) = getADotDotSlashMatcher()
|
||||
|
|
||||
literal.getRoot() = term
|
||||
or
|
||||
exists(RegExpSequence seq | seq.getNumChild() = 2 and literal.getRoot() = seq |
|
||||
seq.getChild(0) instanceof RegExpCaret and
|
||||
seq.getChild(1) = term
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the input path to be sanitized.
|
||||
*/
|
||||
DataFlow::Node getInput() { result = input }
|
||||
|
||||
/**
|
||||
* Gets the path where prefix "../" has been removed.
|
||||
*/
|
||||
DataFlow::Node getOutput() { result = output }
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a RegExpTerm that matches a variation of "../".
|
||||
*/
|
||||
private RegExpTerm getADotDotSlashMatcher() {
|
||||
result.getAMatchedString() = "../"
|
||||
or
|
||||
exists(RegExpSequence seq | seq = result |
|
||||
seq.getChild(0).getConstantValue() = "." and
|
||||
seq.getChild(1).getConstantValue() = "." and
|
||||
seq.getAChild().getAMatchedString() = "/"
|
||||
)
|
||||
or
|
||||
exists(RegExpGroup group | result = group | group.getChild(0) = getADotDotSlashMatcher())
|
||||
}
|
||||
|
||||
/**
|
||||
* A call that removes all "." or ".." from a path, without also removing all forward slashes.
|
||||
*/
|
||||
|
|
|
@ -1277,6 +1277,48 @@ nodes
|
|||
| TaintedPath.js:186:29:186:57 | path.re ... /g, '') |
|
||||
| TaintedPath.js:186:29:186:57 | path.re ... /g, '') |
|
||||
| TaintedPath.js:186:29:186:57 | path.re ... /g, '') |
|
||||
| TaintedPath.js:201:29:201:73 | "prefix ... +/, '') |
|
||||
| TaintedPath.js:201:29:201:73 | "prefix ... +/, '') |
|
||||
| TaintedPath.js:201:29:201:73 | "prefix ... +/, '') |
|
||||
| TaintedPath.js:201:29:201:73 | "prefix ... +/, '') |
|
||||
| TaintedPath.js:201:29:201:73 | "prefix ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:43 | path |
|
||||
| TaintedPath.js:201:40:201:43 | path |
|
||||
| TaintedPath.js:201:40:201:43 | path |
|
||||
| TaintedPath.js:201:40:201:43 | path |
|
||||
| TaintedPath.js:201:40:201:43 | path |
|
||||
| TaintedPath.js:201:40:201:43 | path |
|
||||
| TaintedPath.js:201:40:201:43 | path |
|
||||
| TaintedPath.js:201:40:201:43 | path |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') |
|
||||
| TaintedPath.js:202:29:202:54 | pathMod ... e(path) |
|
||||
| TaintedPath.js:202:29:202:54 | pathMod ... e(path) |
|
||||
| TaintedPath.js:202:29:202:54 | pathMod ... e(path) |
|
||||
| TaintedPath.js:202:29:202:54 | pathMod ... e(path) |
|
||||
| TaintedPath.js:202:29:202:84 | pathMod ... +/, '') |
|
||||
| TaintedPath.js:202:29:202:84 | pathMod ... +/, '') |
|
||||
| TaintedPath.js:202:29:202:84 | pathMod ... +/, '') |
|
||||
| TaintedPath.js:202:29:202:84 | pathMod ... +/, '') |
|
||||
| TaintedPath.js:202:29:202:84 | pathMod ... +/, '') |
|
||||
| TaintedPath.js:202:50:202:53 | path |
|
||||
| TaintedPath.js:202:50:202:53 | path |
|
||||
| TaintedPath.js:202:50:202:53 | path |
|
||||
| TaintedPath.js:202:50:202:53 | path |
|
||||
| TaintedPath.js:202:50:202:53 | path |
|
||||
| TaintedPath.js:202:50:202:53 | path |
|
||||
| TaintedPath.js:202:50:202:53 | path |
|
||||
| TaintedPath.js:202:50:202:53 | path |
|
||||
| normalizedPaths.js:11:7:11:27 | path |
|
||||
| normalizedPaths.js:11:7:11:27 | path |
|
||||
| normalizedPaths.js:11:7:11:27 | path |
|
||||
|
@ -4385,6 +4427,22 @@ edges
|
|||
| TaintedPath.js:173:7:173:48 | path | TaintedPath.js:186:29:186:32 | path |
|
||||
| TaintedPath.js:173:7:173:48 | path | TaintedPath.js:186:29:186:32 | path |
|
||||
| TaintedPath.js:173:7:173:48 | path | TaintedPath.js:186:29:186:32 | path |
|
||||
| TaintedPath.js:173:7:173:48 | path | TaintedPath.js:201:40:201:43 | path |
|
||||
| TaintedPath.js:173:7:173:48 | path | TaintedPath.js:201:40:201:43 | path |
|
||||
| TaintedPath.js:173:7:173:48 | path | TaintedPath.js:201:40:201:43 | path |
|
||||
| TaintedPath.js:173:7:173:48 | path | TaintedPath.js:201:40:201:43 | path |
|
||||
| TaintedPath.js:173:7:173:48 | path | TaintedPath.js:201:40:201:43 | path |
|
||||
| TaintedPath.js:173:7:173:48 | path | TaintedPath.js:201:40:201:43 | path |
|
||||
| TaintedPath.js:173:7:173:48 | path | TaintedPath.js:201:40:201:43 | path |
|
||||
| TaintedPath.js:173:7:173:48 | path | TaintedPath.js:201:40:201:43 | path |
|
||||
| TaintedPath.js:173:7:173:48 | path | TaintedPath.js:202:50:202:53 | path |
|
||||
| TaintedPath.js:173:7:173:48 | path | TaintedPath.js:202:50:202:53 | path |
|
||||
| TaintedPath.js:173:7:173:48 | path | TaintedPath.js:202:50:202:53 | path |
|
||||
| TaintedPath.js:173:7:173:48 | path | TaintedPath.js:202:50:202:53 | path |
|
||||
| TaintedPath.js:173:7:173:48 | path | TaintedPath.js:202:50:202:53 | path |
|
||||
| TaintedPath.js:173:7:173:48 | path | TaintedPath.js:202:50:202:53 | path |
|
||||
| TaintedPath.js:173:7:173:48 | path | TaintedPath.js:202:50:202:53 | path |
|
||||
| TaintedPath.js:173:7:173:48 | path | TaintedPath.js:202:50:202:53 | path |
|
||||
| TaintedPath.js:173:14:173:37 | url.par ... , true) | TaintedPath.js:173:14:173:43 | url.par ... ).query |
|
||||
| TaintedPath.js:173:14:173:37 | url.par ... , true) | TaintedPath.js:173:14:173:43 | url.par ... ).query |
|
||||
| TaintedPath.js:173:14:173:37 | url.par ... , true) | TaintedPath.js:173:14:173:43 | url.par ... ).query |
|
||||
|
@ -4561,6 +4619,62 @@ edges
|
|||
| TaintedPath.js:186:29:186:32 | path | TaintedPath.js:186:29:186:57 | path.re ... /g, '') |
|
||||
| TaintedPath.js:186:29:186:32 | path | TaintedPath.js:186:29:186:57 | path.re ... /g, '') |
|
||||
| TaintedPath.js:186:29:186:32 | path | TaintedPath.js:186:29:186:57 | path.re ... /g, '') |
|
||||
| TaintedPath.js:201:40:201:43 | path | TaintedPath.js:201:40:201:73 | path.re ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:43 | path | TaintedPath.js:201:40:201:73 | path.re ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:43 | path | TaintedPath.js:201:40:201:73 | path.re ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:43 | path | TaintedPath.js:201:40:201:73 | path.re ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:43 | path | TaintedPath.js:201:40:201:73 | path.re ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:43 | path | TaintedPath.js:201:40:201:73 | path.re ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:43 | path | TaintedPath.js:201:40:201:73 | path.re ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:43 | path | TaintedPath.js:201:40:201:73 | path.re ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:43 | path | TaintedPath.js:201:40:201:73 | path.re ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:43 | path | TaintedPath.js:201:40:201:73 | path.re ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:43 | path | TaintedPath.js:201:40:201:73 | path.re ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:43 | path | TaintedPath.js:201:40:201:73 | path.re ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:43 | path | TaintedPath.js:201:40:201:73 | path.re ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:43 | path | TaintedPath.js:201:40:201:73 | path.re ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:43 | path | TaintedPath.js:201:40:201:73 | path.re ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:43 | path | TaintedPath.js:201:40:201:73 | path.re ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') | TaintedPath.js:201:29:201:73 | "prefix ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') | TaintedPath.js:201:29:201:73 | "prefix ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') | TaintedPath.js:201:29:201:73 | "prefix ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') | TaintedPath.js:201:29:201:73 | "prefix ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') | TaintedPath.js:201:29:201:73 | "prefix ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') | TaintedPath.js:201:29:201:73 | "prefix ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') | TaintedPath.js:201:29:201:73 | "prefix ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') | TaintedPath.js:201:29:201:73 | "prefix ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') | TaintedPath.js:201:29:201:73 | "prefix ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') | TaintedPath.js:201:29:201:73 | "prefix ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') | TaintedPath.js:201:29:201:73 | "prefix ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') | TaintedPath.js:201:29:201:73 | "prefix ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') | TaintedPath.js:201:29:201:73 | "prefix ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') | TaintedPath.js:201:29:201:73 | "prefix ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') | TaintedPath.js:201:29:201:73 | "prefix ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') | TaintedPath.js:201:29:201:73 | "prefix ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') | TaintedPath.js:201:29:201:73 | "prefix ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') | TaintedPath.js:201:29:201:73 | "prefix ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') | TaintedPath.js:201:29:201:73 | "prefix ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') | TaintedPath.js:201:29:201:73 | "prefix ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') | TaintedPath.js:201:29:201:73 | "prefix ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') | TaintedPath.js:201:29:201:73 | "prefix ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') | TaintedPath.js:201:29:201:73 | "prefix ... +/, '') |
|
||||
| TaintedPath.js:201:40:201:73 | path.re ... +/, '') | TaintedPath.js:201:29:201:73 | "prefix ... +/, '') |
|
||||
| TaintedPath.js:202:29:202:54 | pathMod ... e(path) | TaintedPath.js:202:29:202:84 | pathMod ... +/, '') |
|
||||
| TaintedPath.js:202:29:202:54 | pathMod ... e(path) | TaintedPath.js:202:29:202:84 | pathMod ... +/, '') |
|
||||
| TaintedPath.js:202:29:202:54 | pathMod ... e(path) | TaintedPath.js:202:29:202:84 | pathMod ... +/, '') |
|
||||
| TaintedPath.js:202:29:202:54 | pathMod ... e(path) | TaintedPath.js:202:29:202:84 | pathMod ... +/, '') |
|
||||
| TaintedPath.js:202:29:202:54 | pathMod ... e(path) | TaintedPath.js:202:29:202:84 | pathMod ... +/, '') |
|
||||
| TaintedPath.js:202:29:202:54 | pathMod ... e(path) | TaintedPath.js:202:29:202:84 | pathMod ... +/, '') |
|
||||
| TaintedPath.js:202:29:202:54 | pathMod ... e(path) | TaintedPath.js:202:29:202:84 | pathMod ... +/, '') |
|
||||
| TaintedPath.js:202:29:202:54 | pathMod ... e(path) | TaintedPath.js:202:29:202:84 | pathMod ... +/, '') |
|
||||
| TaintedPath.js:202:50:202:53 | path | TaintedPath.js:202:29:202:54 | pathMod ... e(path) |
|
||||
| TaintedPath.js:202:50:202:53 | path | TaintedPath.js:202:29:202:54 | pathMod ... e(path) |
|
||||
| TaintedPath.js:202:50:202:53 | path | TaintedPath.js:202:29:202:54 | pathMod ... e(path) |
|
||||
| TaintedPath.js:202:50:202:53 | path | TaintedPath.js:202:29:202:54 | pathMod ... e(path) |
|
||||
| TaintedPath.js:202:50:202:53 | path | TaintedPath.js:202:29:202:54 | pathMod ... e(path) |
|
||||
| TaintedPath.js:202:50:202:53 | path | TaintedPath.js:202:29:202:54 | pathMod ... e(path) |
|
||||
| TaintedPath.js:202:50:202:53 | path | TaintedPath.js:202:29:202:54 | pathMod ... e(path) |
|
||||
| TaintedPath.js:202:50:202:53 | path | TaintedPath.js:202:29:202:54 | pathMod ... e(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 |
|
||||
| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:13:19:13:22 | path |
|
||||
|
@ -6391,6 +6505,8 @@ edges
|
|||
| TaintedPath.js:184:29:184:53 | path.re ... /g, '') | TaintedPath.js:173:24:173:30 | req.url | TaintedPath.js:184:29:184:53 | path.re ... /g, '') | This path depends on $@. | TaintedPath.js:173:24:173:30 | req.url | a user-provided value |
|
||||
| TaintedPath.js:185:29:185:51 | path.re ... /g, '') | TaintedPath.js:173:24:173:30 | req.url | TaintedPath.js:185:29:185:51 | path.re ... /g, '') | This path depends on $@. | TaintedPath.js:173:24:173:30 | req.url | a user-provided value |
|
||||
| TaintedPath.js:186:29:186:57 | path.re ... /g, '') | TaintedPath.js:173:24:173:30 | req.url | TaintedPath.js:186:29:186:57 | path.re ... /g, '') | This path depends on $@. | TaintedPath.js:173:24:173:30 | req.url | a user-provided value |
|
||||
| TaintedPath.js:201:29:201:73 | "prefix ... +/, '') | TaintedPath.js:173:24:173:30 | req.url | TaintedPath.js:201:29:201:73 | "prefix ... +/, '') | This path depends on $@. | TaintedPath.js:173:24:173:30 | req.url | a user-provided value |
|
||||
| TaintedPath.js:202:29:202:84 | pathMod ... +/, '') | TaintedPath.js:173:24:173:30 | req.url | TaintedPath.js:202:29:202:84 | pathMod ... +/, '') | This path depends on $@. | TaintedPath.js:173:24:173:30 | 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 |
|
||||
|
|
|
@ -191,4 +191,13 @@ var server = http.createServer(function(req, res) {
|
|||
res.write(fs.readFileSync(path.replace(/\./g, ''))); // OK
|
||||
res.write(fs.readFileSync(path.replace(/\.\.|BLA/g, ''))); // OK
|
||||
}
|
||||
|
||||
// removing of "../" from prefix.
|
||||
res.write(fs.readFileSync("prefix" + pathModule.normalize(path).replace(/^(\.\.[\/\\])+/, ''))); // OK
|
||||
res.write(fs.readFileSync("prefix" + pathModule.normalize(path).replace(/(\.\.[\/\\])+/, ''))); // OK
|
||||
res.write(fs.readFileSync("prefix" + pathModule.normalize(path).replace(/(\.\.\/)+/, ''))); // OK
|
||||
res.write(fs.readFileSync("prefix" + pathModule.normalize(path).replace(/(\.\.\/)*/, ''))); // OK
|
||||
|
||||
res.write(fs.readFileSync("prefix" + path.replace(/^(\.\.[\/\\])+/, ''))); // NOT OK - not normalized
|
||||
res.write(fs.readFileSync(pathModule.normalize(path).replace(/^(\.\.[\/\\])+/, ''))); // NOT OK (can be absolute)
|
||||
});
|
Загрузка…
Ссылка в новой задаче