@@ -20,125 +20,6 @@ private string getTokenFeature(DataFlow::Node endpoint, string featureName) {
2020 featureName = getASupportedFeatureName ( )
2121}
2222
23- /**
24- * This module provides functionality for getting a representation of the access path of nodes
25- * within the program.
26- *
27- * For example, it gives the `User.find` callee here:
28- *
29- * ```js
30- * const mongoose = require('mongoose'),
31- * User = mongoose.model('User', null);
32- * User.find({ 'isAdmin': true })
33- * ```
34- * the access path `mongoose member model instanceorreturn member find instanceorreturn`.
35- *
36- * This access path is based on the simplified access path that the untrusted data flowing to
37- * external API query associates to each of its sinks, with modifications to optionally include
38- * explicit structural information and to improve how well the path tokenizes.
39- */
40- private module AccessPaths {
41- bindingset [ str]
42- private predicate isNumericString ( string str ) { exists ( str .toInt ( ) ) }
43-
44- /**
45- * Gets a parameter of `base` with name `name`, or a property named `name` of a destructuring parameter.
46- */
47- private API:: Node getNamedParameter ( API:: Node base , string name ) {
48- exists ( API:: Node param |
49- param = base .getAParameter ( ) and
50- not param = base .getReceiver ( )
51- |
52- result = param and
53- name = param .asSource ( ) .asExpr ( ) .( Parameter ) .getName ( )
54- or
55- param .asSource ( ) .asExpr ( ) instanceof DestructuringPattern and
56- result = param .getMember ( name )
57- )
58- }
59-
60- /**
61- * A utility class that is equivalent to `boolean` but does not require type joining.
62- */
63- class Boolean extends boolean {
64- Boolean ( ) { this = true or this = false }
65- }
66-
67- /** Get the access path for the node. This includes structural information like `member`, `param`, and `functionalarg` if `includeStructuralInfo` is true. */
68- predicate accessPaths (
69- API:: Node node , Boolean includeStructuralInfo , string accessPath , string apiName
70- ) {
71- //node = API::moduleImport(result)
72- node = API:: moduleImport ( apiName ) and
73- accessPath = apiName
74- or
75- exists ( API:: Node previousNode , string previousAccessPath |
76- previousNode .getDepth ( ) < node .getDepth ( ) and
77- accessPaths ( previousNode , includeStructuralInfo , previousAccessPath , apiName )
78- |
79- // e.g. `new X`, `X()`
80- node = [ previousNode .getInstance ( ) , previousNode .getReturn ( ) ] and
81- if includeStructuralInfo = true
82- then accessPath = previousAccessPath + " instanceorreturn"
83- else accessPath = previousAccessPath
84- or
85- // e.g. `x.y`, `x[y]`, `const { y } = x`, where `y` is non-numeric and is known at analysis
86- // time.
87- exists ( string member |
88- node = previousNode .getMember ( member ) and
89- not node = previousNode .getUnknownMember ( ) and
90- not isNumericString ( member ) and
91- not ( member = "default" and previousNode = API:: moduleImport ( _) ) and
92- not member = "then" // use the 'promised' edges for .then callbacks
93- |
94- if includeStructuralInfo = true
95- then accessPath = previousAccessPath + " member " + member
96- else accessPath = previousAccessPath + " " + member
97- )
98- or
99- // e.g. `x.y`, `x[y]`, `const { y } = x`, where `y` is numeric or not known at analysis time.
100- (
101- node = previousNode .getUnknownMember ( ) or
102- node = previousNode .getMember ( any ( string s | isNumericString ( s ) ) )
103- ) and
104- if includeStructuralInfo = true
105- then accessPath = previousAccessPath + " member"
106- else accessPath = previousAccessPath
107- or
108- // e.g. `x.then(y => ...)`
109- node = previousNode .getPromised ( ) and
110- accessPath = previousAccessPath
111- or
112- // e.g. `x.y((a, b) => ...)`
113- // Name callback parameters after their name in the source code.
114- // For example, the `res` parameter in `express.get('/foo', (req, res) => {...})` will be
115- // named `express member get functionalarg param res`.
116- exists ( string paramName |
117- node = getNamedParameter ( previousNode .getAParameter ( ) , paramName ) and
118- (
119- if includeStructuralInfo = true
120- then accessPath = previousAccessPath + " functionalarg param " + paramName
121- else accessPath = previousAccessPath + " " + paramName
122- )
123- or
124- exists ( string callbackName , int index |
125- node =
126- getNamedParameter ( previousNode
127- .getASuccessor ( API:: Label:: parameter ( index ) )
128- .getMember ( callbackName ) , paramName ) and
129- index != - 1 and // ignore receiver
130- if includeStructuralInfo = true
131- then
132- accessPath =
133- previousAccessPath + " functionalarg " + index + " " + callbackName + " param " +
134- paramName
135- else accessPath = previousAccessPath + " " + index + " " + callbackName + " " + paramName
136- )
137- )
138- )
139- }
140- }
141-
14223private module FunctionNames {
14324 /**
14425 * Get the name of the function.
0 commit comments