Skip to content

Commit 9cb7522

Browse files
committed
change RouteSetup to a DataFlow::Node
1 parent d98028b commit 9cb7522

30 files changed

+124
-120
lines changed

javascript/ql/lib/semmle/javascript/frameworks/Connect.qll

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,17 +59,17 @@ module Connect {
5959
/**
6060
* A call to a Connect method that sets up a route.
6161
*/
62-
class RouteSetup extends MethodCallExpr, HTTP::Servers::StandardRouteSetup {
62+
class RouteSetup extends DataFlow::MethodCallNode, HTTP::Servers::StandardRouteSetup {
6363
ServerDefinition server;
6464

6565
RouteSetup() {
6666
getMethodName() = "use" and
6767
(
6868
// app.use(fun)
69-
server.ref().flowsToExpr(getReceiver())
69+
server.ref().getAMethodCall() = this
7070
or
7171
// app.use(...).use(fun)
72-
this.getReceiver().(RouteSetup).getServer() = server.asExpr()
72+
this.getReceiver().(RouteSetup).getServer() = server
7373
)
7474
}
7575

@@ -84,10 +84,10 @@ module Connect {
8484
exists(DataFlow::TypeBackTracker t2 | result = getARouteHandler(t2).backtrack(t2, t))
8585
}
8686

87-
override Expr getServer() { result = server.asExpr() }
87+
override DataFlow::Node getServer() { result = server }
8888

8989
/** Gets an argument that represents a route handler being registered. */
90-
Expr getARouteHandlerExpr() { result = getAnArgument() }
90+
Expr getARouteHandlerExpr() { result = getAnArgument().asExpr() } // TODO: DataFlow::Node
9191
}
9292

9393
/** An expression that is passed as `basicAuthConnect(<user>, <password>)`. */

javascript/ql/lib/semmle/javascript/frameworks/Express.qll

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ module Express {
4949
* Holds if `e` may refer to a router object.
5050
*/
5151
private predicate isRouter(Expr e) {
52+
// TODO: DataFlow::Node
5253
isRouter(e, _)
5354
or
5455
e.getType().hasUnderlyingType("express", "Router")
@@ -89,7 +90,7 @@ module Express {
8990
}
9091

9192
private class RoutingTreeSetup extends Routing::RouteSetup::MethodCall {
92-
RoutingTreeSetup() { this.asExpr() instanceof RouteSetup }
93+
RoutingTreeSetup() { this instanceof RouteSetup }
9394

9495
override string getRelativePath() {
9596
not this.getMethodName() = "param" and // do not treat parameter name as a path
@@ -140,17 +141,17 @@ module Express {
140141
/**
141142
* A call to an Express router method that sets up a route.
142143
*/
143-
class RouteSetup extends HTTP::Servers::StandardRouteSetup, MethodCallExpr {
144+
class RouteSetup extends HTTP::Servers::StandardRouteSetup, DataFlow::MethodCallNode {
144145
RouteSetup() {
145-
isRouter(this.getReceiver()) and
146+
isRouter(this.getReceiver().asExpr()) and
146147
this.getMethodName() = routeSetupMethodName()
147148
}
148149

149150
/** Gets the path associated with the route. */
150151
string getPath() { this.getArgument(0).mayHaveStringValue(result) }
151152

152153
/** Gets the router on which handlers are being registered. */
153-
RouterDefinition getRouter() { isRouter(this.getReceiver(), result) }
154+
RouterDefinition getRouter() { isRouter(this.getReceiver().asExpr(), result) }
154155

155156
/** Holds if this is a call `use`, such as `app.use(handler)`. */
156157
predicate isUseCall() { this.getMethodName() = "use" }
@@ -162,13 +163,14 @@ module Express {
162163
* returned, not its dataflow source.
163164
*/
164165
Expr getRouteHandlerExpr(int index) {
166+
// TODO: DataFlow::Node
165167
// The first argument is a URI pattern if it is a string. If it could possibly be
166168
// a function, we consider it to be a route handler, otherwise a URI pattern.
167169
exists(AnalyzedNode firstArg | firstArg = this.getArgument(0).analyze() |
168170
if firstArg.getAType() = TTFunction()
169-
then result = this.getArgument(index)
171+
then result = this.getArgument(index).asExpr()
170172
else (
171-
index >= 0 and result = this.getArgument(index + 1)
173+
index >= 0 and result = this.getArgument(index + 1).asExpr()
172174
)
173175
)
174176
}
@@ -199,9 +201,8 @@ module Express {
199201
)
200202
}
201203

202-
override Expr getServer() {
203-
any(DataFlow::Node n | n.asExpr() = result).(Application).getARouteHandler() =
204-
this.getARouteHandler()
204+
override DataFlow::Node getServer() {
205+
result.(Application).getARouteHandler() = this.getARouteHandler()
205206
}
206207

207208
/**
@@ -236,24 +237,24 @@ module Express {
236237
/**
237238
* A call that sets up a Passport router that includes the request object.
238239
*/
239-
private class PassportRouteSetup extends HTTP::Servers::StandardRouteSetup, CallExpr {
240+
private class PassportRouteSetup extends HTTP::Servers::StandardRouteSetup, DataFlow::CallNode {
240241
DataFlow::ModuleImportNode importNode;
241242
DataFlow::FunctionNode callback;
242243

243244
// looks for this pattern: passport.use(new Strategy({passReqToCallback: true}, callback))
244245
PassportRouteSetup() {
245246
importNode = DataFlow::moduleImport("passport") and
246-
this = importNode.getAMemberCall("use").asExpr() and
247+
this = importNode.getAMemberCall("use") and
247248
exists(DataFlow::NewNode strategy |
248-
strategy.flowsToExpr(this.getArgument(0)) and
249+
strategy.flowsTo(this.getArgument(0)) and
249250
strategy.getNumArgument() = 2 and
250251
// new Strategy({passReqToCallback: true}, ...)
251252
strategy.getOptionArgument(0, "passReqToCallback").mayHaveBooleanValue(true) and
252253
callback.flowsTo(strategy.getArgument(1))
253254
)
254255
}
255256

256-
override Expr getServer() { result = importNode.asExpr() }
257+
override DataFlow::Node getServer() { result = importNode }
257258

258259
override DataFlow::SourceNode getARouteHandler() { result = callback }
259260
}
@@ -335,7 +336,8 @@ module Express {
335336
* same requests.
336337
*/
337338
Express::RouteHandlerExpr getPreviousMiddleware() {
338-
index = 0 and result = setup.getRouter().getMiddlewareStackAt(setup.getAPredecessor())
339+
index = 0 and
340+
result = setup.getRouter().getMiddlewareStackAt(setup.asExpr().getAPredecessor())
339341
or
340342
index > 0 and result = setup.getRouteHandlerExpr(index - 1)
341343
or
@@ -867,15 +869,15 @@ module Express {
867869
/**
868870
* Gets a `RouteSetup` that was used for setting up a route on this router.
869871
*/
870-
private RouteSetup getARouteSetup() { this.ref().flowsToExpr(result.getReceiver()) }
872+
private RouteSetup getARouteSetup() { this.ref().flowsTo(result.getReceiver()) }
871873

872874
/**
873875
* Gets a sub-router registered on this router.
874876
*
875877
* Example: `router2` for `router1.use(router2)` or `router1.use("/route2", router2)`
876878
*/
877879
RouterDefinition getASubRouter() {
878-
result.ref().flowsToExpr(this.getARouteSetup().getAnArgument())
880+
result.ref().flowsTo(this.getARouteSetup().getAnArgument())
879881
}
880882

881883
/**
@@ -884,7 +886,7 @@ module Express {
884886
* Example: `fun` for `router1.use(fun)` or `router.use("/route", fun)`
885887
*/
886888
HTTP::RouteHandler getARouteHandler() {
887-
result.(DataFlow::SourceNode).flowsToExpr(this.getARouteSetup().getAnArgument())
889+
result.(DataFlow::SourceNode).flowsToExpr(this.getARouteSetup().getAnArgument().asExpr())
888890
}
889891

890892
/**
@@ -904,10 +906,10 @@ module Express {
904906
*/
905907
Express::RouteHandlerExpr getMiddlewareStackAt(ControlFlowNode node) {
906908
if
907-
exists(Express::RouteSetup setup | node = setup and setup.getRouter() = this |
909+
exists(Express::RouteSetup setup | node = setup.asExpr() and setup.getRouter() = this |
908910
setup.isUseCall()
909911
)
910-
then result = node.(Express::RouteSetup).getLastRouteHandlerExpr()
912+
then result = node.(AST::ValueNode).flow().(Express::RouteSetup).getLastRouteHandlerExpr()
911913
else result = this.getMiddlewareStackAt(node.getAPredecessor())
912914
}
913915

javascript/ql/lib/semmle/javascript/frameworks/Fastify.qll

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -132,12 +132,12 @@ module Fastify {
132132
/**
133133
* A call to a Fastify method that sets up a route.
134134
*/
135-
class RouteSetup extends MethodCallExpr, HTTP::Servers::StandardRouteSetup {
135+
class RouteSetup extends DataFlow::MethodCallNode, HTTP::Servers::StandardRouteSetup {
136136
ServerDefinition server;
137137
string methodName;
138138

139139
RouteSetup() {
140-
this = server(server).getAMethodCall(methodName).asExpr() and
140+
this = server(server).getAMethodCall(methodName) and
141141
methodName = ["route", "get", "head", "post", "put", "delete", "options", "patch"]
142142
}
143143

@@ -152,20 +152,19 @@ module Fastify {
152152
exists(DataFlow::TypeBackTracker t2 | result = this.getARouteHandler(t2).backtrack(t2, t))
153153
}
154154

155-
override Expr getServer() { result = server.asExpr() }
155+
override DataFlow::SourceNode getServer() { result = server }
156156

157157
/** Gets an argument that represents a route handler being registered. */
158158
DataFlow::Node getARouteHandlerExpr() {
159159
if methodName = "route"
160-
then
161-
result = this.flow().(DataFlow::MethodCallNode).getOptionArgument(0, getNthHandlerName(_))
162-
else result = this.getLastArgument().flow()
160+
then result = this.getOptionArgument(0, getNthHandlerName(_))
161+
else result = this.getLastArgument()
163162
}
164163
}
165164

166165
private class ShorthandRoutingTreeSetup extends Routing::RouteSetup::MethodCall {
167166
ShorthandRoutingTreeSetup() {
168-
this.asExpr() instanceof RouteSetup and
167+
this instanceof RouteSetup and
169168
not this.getMethodName() = "route"
170169
}
171170

@@ -183,7 +182,7 @@ module Fastify {
183182

184183
private class FullRoutingTreeSetup extends Routing::RouteSetup::MethodCall {
185184
FullRoutingTreeSetup() {
186-
this.asExpr() instanceof RouteSetup and
185+
this instanceof RouteSetup and
187186
this.getMethodName() = "route"
188187
}
189188

@@ -285,13 +284,7 @@ module Fastify {
285284
*/
286285
private predicate usesFastifyPlugin(RouteHandler rh, DataFlow::SourceNode plugin) {
287286
exists(RouteSetup setup |
288-
plugin
289-
.flowsTo(setup
290-
.getServer()
291-
.flow()
292-
.(DataFlow::SourceNode)
293-
.getAMethodCall("register")
294-
.getArgument(0)) and // only matches the plugins that apply to all routes
287+
plugin.flowsTo(setup.getServer().getAMethodCall("register").getArgument(0)) and // only matches the plugins that apply to all routes
295288
rh = setup.getARouteHandler()
296289
)
297290
}
@@ -301,13 +294,7 @@ module Fastify {
301294
*/
302295
private predicate usesMiddleware(RouteHandler rh, DataFlow::SourceNode middleware) {
303296
exists(RouteSetup setup |
304-
middleware
305-
.flowsTo(setup
306-
.getServer()
307-
.flow()
308-
.(DataFlow::SourceNode)
309-
.getAMethodCall("use")
310-
.getArgument(0)) and // only matches the middlewares that apply to all routes
297+
middleware.flowsTo(setup.getServer().getAMethodCall("use").getArgument(0)) and // only matches the middlewares that apply to all routes
311298
rh = setup.getARouteHandler()
312299
)
313300
}

javascript/ql/lib/semmle/javascript/frameworks/Firebase.qll

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -195,23 +195,21 @@ module Firebase {
195195
/**
196196
* A call to a Firebase method that sets up a route.
197197
*/
198-
private class RouteSetup extends HTTP::Servers::StandardRouteSetup, CallExpr {
199-
RouteSetup() {
200-
this = namespace().getAPropertyRead("https").getAMemberCall("onRequest").asExpr()
201-
}
198+
private class RouteSetup extends HTTP::Servers::StandardRouteSetup, DataFlow::CallNode {
199+
RouteSetup() { this = namespace().getAPropertyRead("https").getAMemberCall("onRequest") }
202200

203201
override DataFlow::SourceNode getARouteHandler() {
204202
result = getARouteHandler(DataFlow::TypeBackTracker::end())
205203
}
206204

207205
private DataFlow::SourceNode getARouteHandler(DataFlow::TypeBackTracker t) {
208206
t.start() and
209-
result = getArgument(0).flow().getALocalSource()
207+
result = getArgument(0).getALocalSource()
210208
or
211209
exists(DataFlow::TypeBackTracker t2 | result = getARouteHandler(t2).backtrack(t2, t))
212210
}
213211

214-
override Expr getServer() { none() }
212+
override DataFlow::Node getServer() { none() }
215213
}
216214

217215
/**

javascript/ql/lib/semmle/javascript/frameworks/HTTP.qll

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ module HTTP {
242242
/**
243243
* An expression that sets up a route on a server.
244244
*/
245-
abstract class RouteSetup extends Expr { } // TODO: DataFlow::Node
245+
abstract class RouteSetup extends DataFlow::Node { }
246246

247247
/**
248248
* An expression that may contain a request object.
@@ -275,9 +275,7 @@ module HTTP {
275275
* A standard server definition.
276276
*/
277277
abstract class StandardServerDefinition extends ServerDefinition {
278-
override RouteHandler getARouteHandler() {
279-
result.(StandardRouteHandler).getServer() = this.asExpr()
280-
}
278+
override RouteHandler getARouteHandler() { result.(StandardRouteHandler).getServer() = this }
281279

282280
private DataFlow::SourceNode ref(DataFlow::TypeTracker t) {
283281
t.start() and
@@ -308,8 +306,7 @@ module HTTP {
308306
/**
309307
* Gets the server this route handler is registered on.
310308
*/
311-
Expr getServer() {
312-
// TODO: DataFlow::Node
309+
DataFlow::Node getServer() {
313310
exists(StandardRouteSetup setup | setup.getARouteHandler() = this |
314311
result = setup.getServer()
315312
)
@@ -414,7 +411,7 @@ module HTTP {
414411
/**
415412
* Gets the server on which this route setup sets up routes.
416413
*/
417-
abstract Expr getServer(); // TODO: DataFlow::Node
414+
abstract DataFlow::Node getServer();
418415
}
419416

420417
/**

javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -186,16 +186,16 @@ module Hapi {
186186
/**
187187
* A call to a Hapi method that sets up a route.
188188
*/
189-
class RouteSetup extends MethodCallExpr, HTTP::Servers::StandardRouteSetup {
189+
class RouteSetup extends DataFlow::MethodCallNode, HTTP::Servers::StandardRouteSetup {
190190
ServerDefinition server;
191-
Expr handler;
191+
DataFlow::Node handler;
192192

193193
RouteSetup() {
194-
server.ref().flowsToExpr(getReceiver()) and
194+
server.ref().getAMethodCall() = this and
195195
(
196196
// server.route({ handler: fun })
197197
getMethodName() = "route" and
198-
hasOptionArgument(0, "handler", handler)
198+
getOptionArgument(0, "handler") = handler
199199
or
200200
// server.ext('/', fun)
201201
getMethodName() = "ext" and
@@ -215,11 +215,11 @@ module Hapi {
215215
}
216216

217217
pragma[noinline]
218-
private DataFlow::Node getRouteHandler() { result = handler.flow() }
218+
private DataFlow::Node getRouteHandler() { result = handler }
219219

220-
Expr getRouteHandlerExpr() { result = handler }
220+
Expr getRouteHandlerExpr() { result = handler.asExpr() } // TODO: DataFlow::Node
221221

222-
override Expr getServer() { result = server.asExpr() }
222+
override DataFlow::Node getServer() { result = server }
223223
}
224224

225225
/**

javascript/ql/lib/semmle/javascript/frameworks/Koa.qll

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -384,24 +384,23 @@ module Koa {
384384
/**
385385
* A call to a Koa method that sets up a route.
386386
*/
387-
class RouteSetup extends HTTP::Servers::StandardRouteSetup, MethodCallExpr {
387+
class RouteSetup extends HTTP::Servers::StandardRouteSetup, DataFlow::MethodCallNode {
388388
AppDefinition server;
389389

390390
RouteSetup() {
391391
// app.use(fun)
392-
server.ref().flowsToExpr(this.getReceiver()) and
393-
this.getMethodName() = "use"
392+
server.ref().getAMethodCall("use") = this
394393
}
395394

396395
override DataFlow::SourceNode getARouteHandler() {
397396
// `StandardRouteHandler` uses this predicate in it's charpred, so making this predicate return a `RouteHandler` would give an empty recursion.
398-
result.flowsToExpr(this.getArgument(0))
397+
result.flowsToExpr(this.getArgument(0).asExpr())
399398
or
400399
// For the route-handlers that does not depend on this predicate in their charpred.
401-
result.(RouteHandler).getARouteHandlerRegistrationObject().flowsToExpr(this.getArgument(0))
400+
result.(RouteHandler).getARouteHandlerRegistrationObject().flowsTo(this.getArgument(0))
402401
}
403402

404-
override Expr getServer() { result = server.asExpr() }
403+
override DataFlow::Node getServer() { result = server }
405404
}
406405

407406
/**

0 commit comments

Comments
 (0)