@@ -36,13 +36,14 @@ module TaintedLength {
3636 class ArrayIterationLoop extends Stmt {
3737 LocalVariable indexVariable ;
3838 LoopStmt loop ;
39+ DataFlow:: PropRead lengthRead ;
3940
4041 ArrayIterationLoop ( ) {
4142 this = loop and
42- exists ( RelationalComparison compare , DataFlow :: PropRead lengthRead |
43+ exists ( RelationalComparison compare |
4344 compare = loop .getTest ( ) and
4445 compare .getLesserOperand ( ) = indexVariable .getAnAccess ( ) and
45- lengthRead .accesses ( _ , "length" ) and
46+ lengthRead .getPropertyName ( ) = "length" and
4647 lengthRead .flowsToExpr ( compare .getGreaterOperand ( ) )
4748 ) and
4849 (
@@ -51,6 +52,13 @@ module TaintedLength {
5152 )
5253 }
5354
55+ /**
56+ * Gets the length read in the loop test
57+ */
58+ DataFlow:: PropRead getLengthRead ( ) {
59+ result = lengthRead
60+ }
61+
5462 /**
5563 * Gets the loop test of this loop.
5664 */
@@ -77,19 +85,17 @@ module TaintedLength {
7785 abstract class Sink extends DataFlow:: Node { }
7886
7987 /**
80- * A loop that iterates over an array , such as `for (..; .. sink.length; ...) ...`
88+ * An object that that is being iterated in a `for` loop , such as `for (..; .. sink.length; ...) ...`
8189 */
8290 private class LoopSink extends Sink {
8391 LoopSink ( ) {
84- exists ( ArrayIterationLoop loop , Expr lengthAccess , DataFlow:: PropRead lengthRead |
85- loop .getTest ( ) .( RelationalComparison ) .getGreaterOperand ( ) = lengthAccess and
86- lengthRead .flowsToExpr ( lengthAccess ) and
87- lengthRead .accesses ( this , "length" ) and
92+ exists ( ArrayIterationLoop loop |
93+ this = loop .getLengthRead ( ) .getBase ( ) and
8894
89- // In the DOS we are looking for arrayRead will evaluate to undefined.
90- // If an obvious nullpointer happens on this undefined, then the DOS cannot happen.
95+ // In the DOS we are looking for arrayRead will evaluate to undefined,
96+ // this may cause an exception to be thrown, thus bailing out of the loop.
97+ // A DoS cannot happen if such an exception is thrown.
9198 not exists ( DataFlow:: PropRead arrayRead , Expr throws |
92- // It doesn't only happen inside the for-loop, outside is also a sink (assuming it happens before).
9399 loop .getBody ( ) .getAChild * ( ) = arrayRead .asExpr ( ) and
94100 loop .getBody ( ) .getAChild * ( ) = throws and
95101 arrayRead .getPropertyNameExpr ( ) = loop .getIndexVariable ( ) .getAnAccess ( ) and
@@ -178,7 +184,7 @@ module TaintedLength {
178184
179185 /**
180186 * A method call to a lodash method that iterates over an array-like structure,
181- * such as `_.filter(sink, ...)`
187+ * such as `_.filter(sink, ...)`.
182188 */
183189 private class LodashIterationSink extends Sink {
184190 DataFlow:: CallNode call ;
@@ -202,7 +208,7 @@ module TaintedLength {
202208 isCrashingWithNullValues ( throws )
203209 )
204210 or
205- // similar to the loop sink - the existance of an early-exit usually means that no DOS can happen.
211+ // similar to the loop sink - the existence of an early-exit usually means that no DOS can happen.
206212 exists ( ThrowStmt throw |
207213 throw = func .asExpr ( ) .( Function ) .getBody ( ) .getAChild * ( ) and
208214 throw .getTarget ( ) = func .asExpr ( )
@@ -214,7 +220,7 @@ module TaintedLength {
214220 }
215221
216222 /**
217- * A source of objects that can cause DOS is looped over.
223+ * A source of objects that can cause DOS if looped over.
218224 */
219225 abstract class Source extends DataFlow:: Node { }
220226
0 commit comments