Skip to content

Commit 425bd7a

Browse files
committed
JS: Model template instantiation from Fastify, Hapi, and Koa
1 parent 266c104 commit 425bd7a

3 files changed

Lines changed: 100 additions & 1 deletion

File tree

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,4 +288,31 @@ module Fastify {
288288
)
289289
}
290290
}
291+
292+
/**
293+
* A call to `rep.view('file', { ... })`, seen as a template instantiation.
294+
*
295+
* Assumes the presense of a plugin that provides the `view` method, such as the `point-of-view` plugin.
296+
*/
297+
private class ViewCall extends Templating::TemplateInstantiaton::Range, DataFlow::CallNode {
298+
ViewCall() {
299+
this = any(ReplySource rep).ref().getAMethodCall("view")
300+
}
301+
302+
override DataFlow::SourceNode getOutput() {
303+
result = getCallback(2).getParameter(1)
304+
}
305+
306+
override DataFlow::Node getTemplateFileNode() {
307+
result = getArgument(0)
308+
}
309+
310+
override DataFlow::Node getTemplateContentNode() {
311+
none()
312+
}
313+
314+
override DataFlow::Node getTemplateParamsNode() {
315+
result = getArgument(1)
316+
}
317+
}
291318
}

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

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,19 @@ module Hapi {
3131
* Gets the parameter of the route handler that contains the request object.
3232
*/
3333
Parameter getRequestParameter() { result = function.getParameter(0) }
34+
35+
/**
36+
* Gets the parameter of the route handler that contains the "request toolkit",
37+
* usually named `h`.
38+
*/
39+
Parameter getRequestToolkitParameter() { result = function.getParameter(1) }
40+
41+
/**
42+
* Gets a source node referring to the request toolkit parameter, usually named `h`.
43+
*/
44+
DataFlow::SourceNode getRequestToolkit() {
45+
result = getRequestToolkitParameter().flow()
46+
}
3447
}
3548

3649
/**
@@ -237,4 +250,29 @@ module Hapi {
237250
HTTP::Servers::StandardRouteHandler, DataFlow::FunctionNode {
238251
TrackedRouteHandlerCandidateWithSetup() { this = any(RouteSetup s).getARouteHandler() }
239252
}
253+
254+
/**
255+
* A call to `h.view('file', { ... })` seen as a template instantiation.
256+
*/
257+
private class ViewCall extends Templating::TemplateInstantiaton::Range, DataFlow::CallNode {
258+
ViewCall() {
259+
this = any(RouteHandler rh).getRequestToolkit().getAMethodCall("view")
260+
}
261+
262+
override DataFlow::SourceNode getOutput() {
263+
none()
264+
}
265+
266+
override DataFlow::Node getTemplateFileNode() {
267+
result = getArgument(0)
268+
}
269+
270+
override DataFlow::Node getTemplateContentNode() {
271+
none()
272+
}
273+
274+
override DataFlow::Node getTemplateParamsNode() {
275+
result = getArgument(1)
276+
}
277+
}
240278
}

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

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,14 +112,19 @@ module Koa {
112112
*/
113113
RouteHandler getRouteHandler() { result = rh }
114114

115-
predicate flowsTo(DataFlow::Node nd) { ref(DataFlow::TypeTracker::end()).flowsTo(nd) }
115+
predicate flowsTo(DataFlow::Node nd) { ref().flowsTo(nd) }
116116

117117
private DataFlow::SourceNode ref(DataFlow::TypeTracker t) {
118118
t.start() and
119119
result = this
120120
or
121121
exists(DataFlow::TypeTracker t2 | result = ref(t2).track(t2, t))
122122
}
123+
124+
/** Gets a source node that refers to this context object. */
125+
DataFlow::SourceNode ref() {
126+
result = ref(DataFlow::TypeTracker::end())
127+
}
123128
}
124129

125130
/**
@@ -424,4 +429,33 @@ module Koa {
424429

425430
override RouteHandler getRouteHandler() { result = rh }
426431
}
432+
433+
/**
434+
* A call to `ctx.render('file', { ... })`, seen as a template instantiation.
435+
*/
436+
private class RenderCall extends Templating::TemplateInstantiaton::Range, DataFlow::CallNode {
437+
ContextSource ctx;
438+
439+
RenderCall() {
440+
this = ctx.ref().getAMethodCall("render")
441+
}
442+
443+
override DataFlow::SourceNode getOutput() {
444+
none()
445+
}
446+
447+
override DataFlow::Node getTemplateFileNode() {
448+
result = getArgument(0)
449+
}
450+
451+
override DataFlow::Node getTemplateContentNode() {
452+
none()
453+
}
454+
455+
override DataFlow::Node getTemplateParamsNode() {
456+
result = getArgument(1)
457+
or
458+
result = ctx.ref().getAPropertyReference("state")
459+
}
460+
}
427461
}

0 commit comments

Comments
 (0)