@@ -584,22 +584,26 @@ module TaintTracking {
584
584
585
585
/**
586
586
* A taint propagating data flow edge for assignments of the form `o[k] = v`, where
587
- * `k` is not a constant and `o` refers to some object literal; in this case, we consider
588
- * taint to flow from `v` to that object literal.
587
+ * one of the following holds:
589
588
*
590
- * The rationale for this heuristic is that if properties of `o` are accessed by
591
- * computed (that is, non-constant) names, then `o` is most likely being treated as
592
- * a map, not as a real object. In this case, it makes sense to consider the entire
593
- * map to be tainted as soon as one of its entries is.
589
+ * - `k` is not a constant and `o` refers to some object literal. The rationale
590
+ * here is that `o` is most likely being used like a dictionary object.
591
+ *
592
+ * - `k` refers to `o.length`, that is, the assignment is of form `o[o.length] = v`.
593
+ * In this case, the assignment behaves like `o.push(v)`.
594
594
*/
595
- private class DictionaryTaintStep extends SharedTaintStep {
595
+ private class ComputedPropWriteTaintStep extends SharedTaintStep {
596
596
override predicate heapStep ( DataFlow:: Node pred , DataFlow:: Node succ ) {
597
- exists ( AssignExpr assgn , IndexExpr idx , DataFlow:: ObjectLiteralNode obj |
597
+ exists ( AssignExpr assgn , IndexExpr idx , DataFlow:: SourceNode obj |
598
598
assgn .getTarget ( ) = idx and
599
599
obj .flowsToExpr ( idx .getBase ( ) ) and
600
600
not exists ( idx .getPropertyName ( ) ) and
601
601
pred = DataFlow:: valueNode ( assgn .getRhs ( ) ) and
602
602
succ = obj
603
+ |
604
+ obj instanceof DataFlow:: ObjectLiteralNode
605
+ or
606
+ obj .getAPropertyRead ( "length" ) .flowsToExpr ( idx .getPropertyNameExpr ( ) )
603
607
)
604
608
}
605
609
}
0 commit comments