@@ -21,42 +21,79 @@ private module MongoDB {
2121 /**
2222 * Gets an access to `mongodb.MongoClient`.
2323 */
24- DataFlow:: SourceNode getAMongoClient ( ) { result = mongodb ( ) .getAPropertyRead ( "MongoClient" ) }
24+ private DataFlow:: SourceNode getAMongoClient ( DataFlow:: TypeTracker t ) {
25+ t .start ( ) and
26+ result = mongodb ( ) .getAPropertyRead ( "MongoClient" )
27+ or
28+ exists ( DataFlow:: TypeTracker t2 | result = getAMongoClient ( t2 ) .track ( t2 , t ) )
29+ }
30+
31+ /**
32+ * Gets an access to `mongodb.MongoClient`.
33+ */
34+ DataFlow:: SourceNode getAMongoClient ( ) { result = getAMongoClient ( DataFlow:: TypeTracker:: end ( ) ) }
35+
36+ /** Gets a data flow node that leads to a `connect` callback. */
37+ private DataFlow:: SourceNode getAMongoDbCallback ( DataFlow:: TypeBackTracker t ) {
38+ t .start ( ) and
39+ result = getAMongoClient ( ) .getAMemberCall ( "connect" ) .getArgument ( 1 ) .getALocalSource ( )
40+ or
41+ exists ( DataFlow:: TypeBackTracker t2 | result = getAMongoDbCallback ( t2 ) .backtrack ( t2 , t ) )
42+ }
43+
44+ /** Gets a data flow node that leads to a `connect` callback. */
45+ private DataFlow:: FunctionNode getAMongoDbCallback ( ) {
46+ result = getAMongoDbCallback ( DataFlow:: TypeBackTracker:: end ( ) )
47+ }
2548
2649 /**
2750 * Gets an expression that may refer to a MongoDB database connection.
2851 */
29- DataFlow:: SourceNode getAMongoDb ( ) {
30- result = getAMongoClient ( ) .getAMemberCall ( "connect" ) .getCallback ( 1 ) .getParameter ( 1 )
52+ private DataFlow:: SourceNode getAMongoDb ( DataFlow:: TypeTracker t ) {
53+ t .start ( ) and
54+ result = getAMongoDbCallback ( ) .getParameter ( 1 )
55+ or
56+ exists ( DataFlow:: TypeTracker t2 | result = getAMongoDb ( t2 ) .track ( t2 , t ) )
3157 }
3258
3359 /**
34- * An expression that may hold a MongoDB collection.
60+ * Gets an expression that may refer to a MongoDB database connection.
61+ */
62+ DataFlow:: SourceNode getAMongoDb ( ) { result = getAMongoDb ( DataFlow:: TypeTracker:: end ( ) ) }
63+
64+ /**
65+ * A data flow node that may hold a MongoDB collection.
3566 */
36- abstract class Collection extends Expr { }
67+ abstract class Collection extends DataFlow :: SourceNode { }
3768
3869 /**
3970 * A collection resulting from calling `Db.collection(...)`.
4071 */
4172 private class CollectionFromDb extends Collection {
4273 CollectionFromDb ( ) {
43- exists ( DataFlow:: CallNode collection |
44- collection = getAMongoDb ( ) .getAMethodCall ( "collection" )
45- |
46- collection .flowsToExpr ( this )
47- or
48- collection .getCallback ( 1 ) .getParameter ( 0 ) .flowsToExpr ( this )
49- )
74+ this = getAMongoDb ( ) .getAMethodCall ( "collection" )
75+ or
76+ this = getAMongoDb ( ) .getAMethodCall ( "collection" ) .getCallback ( 1 ) .getParameter ( 0 )
5077 }
5178 }
5279
80+ /** Gets a data flow node referring to a MongoDB collection. */
81+ private DataFlow:: SourceNode getACollection ( DataFlow:: TypeTracker t ) {
82+ t .start ( ) and
83+ result instanceof Collection
84+ or
85+ exists ( DataFlow:: TypeTracker t2 | result = getACollection ( t2 ) .track ( t2 , t ) )
86+ }
87+
88+ /** Gets a data flow node referring to a MongoDB collection. */
89+ DataFlow:: SourceNode getACollection ( ) { result = getACollection ( DataFlow:: TypeTracker:: end ( ) ) }
90+
5391 /** A call to a MongoDB query method. */
54- private class QueryCall extends DatabaseAccess , DataFlow:: ValueNode {
55- override MethodCallExpr astNode ;
92+ private class QueryCall extends DatabaseAccess , DataFlow:: MethodCallNode {
5693 int queryArgIdx ;
5794
5895 QueryCall ( ) {
59- exists ( string m | asExpr ( ) .( MethodCallExpr ) . calls ( any ( Collection c ) , m ) |
96+ exists ( string m | this = getACollection ( ) .getAMethodCall ( m ) |
6097 m = "aggregate" and queryArgIdx = 0
6198 or
6299 m = "count" and queryArgIdx = 0
@@ -91,9 +128,7 @@ private module MongoDB {
91128 )
92129 }
93130
94- override DataFlow:: Node getAQueryArgument ( ) {
95- result = DataFlow:: valueNode ( astNode .getArgument ( queryArgIdx ) )
96- }
131+ override DataFlow:: Node getAQueryArgument ( ) { result = getArgument ( queryArgIdx ) }
97132 }
98133
99134 /**
@@ -116,15 +151,15 @@ private module Mongoose {
116151 /**
117152 * Gets a call to `mongoose.createConnection`.
118153 */
119- MethodCallExpr createConnection ( ) {
120- result = getAMongooseInstance ( ) .getAMemberCall ( "createConnection" ) . asExpr ( )
154+ DataFlow :: CallNode createConnection ( ) {
155+ result = getAMongooseInstance ( ) .getAMemberCall ( "createConnection" )
121156 }
122157
123158 /**
124159 * A Mongoose collection object.
125160 */
126161 class Model extends MongoDB:: Collection {
127- Model ( ) { getAMongooseInstance ( ) .getAMemberCall ( "model" ) . flowsToExpr ( this ) }
162+ Model ( ) { this = getAMongooseInstance ( ) .getAMemberCall ( "model" ) }
128163 }
129164
130165 /**
@@ -134,7 +169,7 @@ private module Mongoose {
134169 string kind ;
135170
136171 Credentials ( ) {
137- exists ( string prop | createConnection ( ) .hasOptionArgument ( 3 , prop , this ) |
172+ exists ( string prop | this = createConnection ( ) .getOptionArgument ( 3 , prop ) . asExpr ( ) |
138173 prop = "user" and kind = "user name"
139174 or
140175 prop = "pass" and kind = "password"
0 commit comments