Skip to content

Commit 94aa777

Browse files
authored
Merge pull request github#2810 from erik-krogh/CVE74
Approved by asgerf
2 parents 285be28 + 03e295e commit 94aa777

File tree

6 files changed

+785
-8
lines changed

6 files changed

+785
-8
lines changed

javascript/ql/src/semmle/javascript/security/dataflow/TaintedPath.qll

Lines changed: 60 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,68 @@ module TaintedPath {
9393
|
9494
name = argumentlessMethodName
9595
)
96-
or
96+
)
97+
or
98+
// array method calls of interest
99+
exists(DataFlow::MethodCallNode mcn, string name | dst = mcn and mcn.calls(src, name) |
100+
// A `str.split()` call can either split into path elements (`str.split("/")`) or split by some other string.
97101
name = "split" and
98-
not exists(DataFlow::Node splitBy | splitBy = mcn.getArgument(0) |
99-
splitBy.mayHaveStringValue("/") or
100-
any(DataFlow::RegExpLiteralNode reg | reg.getRoot().getAMatchedString() = "/")
101-
.flowsTo(splitBy)
102+
(
103+
if
104+
exists(DataFlow::Node splitBy | splitBy = mcn.getArgument(0) |
105+
splitBy.mayHaveStringValue("/") or
106+
any(DataFlow::RegExpCreationNode reg | reg.getRoot().getAMatchedString() = "/")
107+
.flowsTo(splitBy)
108+
)
109+
then
110+
srclabel.(Label::PosixPath).canContainDotDotSlash() and
111+
dstlabel instanceof Label::SplitPath
112+
else srclabel = dstlabel
102113
)
114+
or
115+
(
116+
name = "pop" or
117+
name = "shift"
118+
) and
119+
srclabel instanceof Label::SplitPath and
120+
dstlabel.(Label::PosixPath).canContainDotDotSlash()
121+
or
122+
(
123+
name = "slice" or
124+
name = "splice" or
125+
name = "concat"
126+
) and
127+
dstlabel instanceof Label::SplitPath and
128+
srclabel instanceof Label::SplitPath
129+
or
130+
name = "join" and
131+
mcn.getArgument(0).mayHaveStringValue("/") and
132+
srclabel instanceof Label::SplitPath and
133+
dstlabel.(Label::PosixPath).canContainDotDotSlash()
134+
)
135+
or
136+
// prefix.concat(path)
137+
exists(DataFlow::MethodCallNode mcn |
138+
mcn.getMethodName() = "concat" and mcn.getAnArgument() = src
139+
|
140+
dst = mcn and
141+
dstlabel instanceof Label::SplitPath and
142+
srclabel instanceof Label::SplitPath
143+
)
144+
or
145+
// reading unknown property of split path
146+
exists(DataFlow::PropRead read | read = dst |
147+
src = read.getBase() and
148+
not read.getPropertyName() = "length" and
149+
not exists(read.getPropertyNameExpr().getIntValue()) and
150+
// split[split.length - 1]
151+
not exists(BinaryExpr binop |
152+
read.getPropertyNameExpr() = binop and
153+
binop.getAnOperand().getIntValue() = 1 and
154+
binop.getAnOperand().(PropAccess).getPropertyName() = "length"
155+
) and
156+
srclabel instanceof Label::SplitPath and
157+
dstlabel.(Label::PosixPath).canContainDotDotSlash()
103158
)
104159
}
105160

javascript/ql/src/semmle/javascript/security/dataflow/TaintedPathCustomizations.qll

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,15 @@ module TaintedPath {
108108
not (isNormalized() and isAbsolute())
109109
}
110110
}
111+
112+
/**
113+
* A flow label representing an array of path elements that may include "..".
114+
*/
115+
class SplitPath extends DataFlow::FlowLabel {
116+
SplitPath() {
117+
this = "splitPath"
118+
}
119+
}
111120
}
112121

113122
/**
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
| normalizedPaths.js:208:38:208:63 | // OK - ... anyway | Spurious alert |
22
| tainted-string-steps.js:25:43:25:74 | // NOT ... flagged | Missing alert |
33
| tainted-string-steps.js:26:49:26:74 | // OK - ... flagged | Spurious alert |
4+
| tainted-string-steps.js:28:39:28:70 | // NOT ... flagged | Missing alert |

0 commit comments

Comments
 (0)