Skip to content

Commit 763da72

Browse files
author
Esben Sparre Andreasen
committed
JS: modernize old array taint steps
1 parent ea37665 commit 763da72

File tree

1 file changed

+21
-24
lines changed

1 file changed

+21
-24
lines changed

javascript/ql/src/semmle/javascript/dataflow/TaintTracking.qll

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -214,36 +214,33 @@ module TaintTracking {
214214
* A taint propagating data flow edge caused by the builtin array functions.
215215
*/
216216
private class ArrayFunctionTaintStep extends AdditionalTaintStep {
217+
DataFlow::CallNode call;
217218

218219
ArrayFunctionTaintStep() {
219-
this = DataFlow::valueNode(_) or
220-
this = DataFlow::parameterNode(_) or
221-
this instanceof DataFlow::PropRead
220+
this = call
222221
}
223222

224223
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
225-
succ = this and (
226-
// `array.map(function (elt, i, ary) { ... })`: if `array` is tainted, then so are
227-
// `elt` and `ary`; similar for `forEach`
228-
exists (MethodCallExpr m, Function f, int i, SimpleParameter p |
229-
(m.getMethodName() = "map" or m.getMethodName() = "forEach") and
230-
(i = 0 or i = 2) and
231-
m.getArgument(0).analyze().getAValue().(AbstractFunction).getFunction() = f and
232-
p = f.getParameter(i) and
233-
this = DataFlow::parameterNode(p) and
234-
pred.asExpr() = m.getReceiver()
235-
)
236-
or
237-
// `array.map` with tainted return value in callback
238-
exists (MethodCallExpr m, Function f |
239-
this.asExpr() = m and
240-
m.getMethodName() = "map" and
241-
m.getArgument(0) = f and // Require the argument to be a closure to avoid spurious call/return flow
242-
pred = f.getAReturnedExpr().flow())
243-
or
244-
// `array.push(e)`: if `e` is tainted, then so is `array`
245-
succ.(DataFlow::SourceNode).getAMethodCall("push").getAnArgument() = pred
224+
// `array.map(function (elt, i, ary) { ... })`: if `array` is tainted, then so are
225+
// `elt` and `ary`; similar for `forEach`
226+
exists (string name, Function f, int i |
227+
(name = "map" or name = "forEach") and
228+
(i = 0 or i = 2) and
229+
call.getArgument(0).analyze().getAValue().(AbstractFunction).getFunction() = f and
230+
pred.(DataFlow::SourceNode).getAMethodCall(name) = call and
231+
succ = DataFlow::parameterNode(f.getParameter(i))
246232
)
233+
or
234+
// `array.map` with tainted return value in callback
235+
exists (DataFlow::FunctionNode f |
236+
call.(DataFlow::MethodCallNode).getMethodName() = "map" and
237+
call.getArgument(0) = f and // Require the argument to be a closure to avoid spurious call/return flow
238+
pred = f.getAReturn() and
239+
succ = call
240+
)
241+
or
242+
// `array.push(e)`: if `e` is tainted, then so is `array`
243+
succ.(DataFlow::SourceNode).getAMethodCall("push") = call
247244
}
248245

249246
}

0 commit comments

Comments
 (0)