@@ -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