Skip to content

Commit ae228cb

Browse files
committed
move new predicates to a more fitting location
1 parent 5fd4c7a commit ae228cb

File tree

4 files changed

+49
-48
lines changed

4 files changed

+49
-48
lines changed

javascript/ql/src/Security/CWE-352/MissingCsrfMiddleware.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ private DataFlow::SourceNode getARouteUsingCookies(DataFlow::TypeTracker t) {
5050
result = pred.track(t2, t)
5151
or
5252
t = t2 and
53-
Express::routeHandlerStep(pred, result)
53+
HTTP::routeHandlerStep(pred, result)
5454
)
5555
}
5656

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

Lines changed: 1 addition & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -72,50 +72,6 @@ module Express {
7272
result = "del"
7373
}
7474

75-
/**
76-
* Holds if `call` decorates the function `pred`.
77-
* This means that `call` returns a function that forwards its arguments to `pred`.
78-
*/
79-
predicate isDecoratedCall(DataFlow::CallNode call, DataFlow::FunctionNode decoratee) {
80-
// indirect route-handler `result` is given to function `outer`, which returns function `inner` which calls the function `pred`.
81-
exists(int i, Function outer, Function inner |
82-
decoratee = call.getArgument(i).getALocalSource() and
83-
outer = call.getACallee() and
84-
inner = outer.getAReturnedExpr() and
85-
isAForwardingRouteHandlerCall(DataFlow::parameterNode(outer.getParameter(i)), inner.flow())
86-
)
87-
}
88-
89-
/**
90-
* Holds if `f` looks like a route-handler and a call to `callee` inside `f` forwards all of the parameters from `f` to that call,
91-
*/
92-
private predicate isAForwardingRouteHandlerCall(DataFlow::SourceNode callee, HTTP::RouteHandlerCandidate f) {
93-
exists(DataFlow::CallNode call | call = callee.getACall() |
94-
forall(int arg | arg = [0 .. f.getNumParameter() - 1] |
95-
f.getParameter(arg).flowsTo(call.getArgument(arg))
96-
) and
97-
call.getContainer() = f.getFunction()
98-
)
99-
}
100-
101-
/**
102-
* Holds if there exists a step from `pred` to `succ` for a RouteHandler - beyond the usual steps defined by TypeTracking.
103-
*/
104-
predicate routeHandlerStep(DataFlow::SourceNode pred, DataFlow::SourceNode succ) {
105-
isDecoratedCall(succ, pred)
106-
or
107-
// A forwarding call
108-
isAForwardingRouteHandlerCall(pred, succ)
109-
or
110-
// a container containing route-handlers.
111-
exists(HTTP::RouteHandlerCandidateContainer container | pred = container.getRouteHandler(succ))
112-
or
113-
// (function (req, res) {}).bind(this);
114-
exists(DataFlow::PartialInvokeNode call |
115-
succ = call.getBoundFunction(pred, 0)
116-
)
117-
}
118-
11975
/**
12076
* A call to an Express router method that sets up a route.
12177
*/
@@ -169,7 +125,7 @@ module Express {
169125
exists(DataFlow::TypeBackTracker t2, DataFlow::SourceNode succ | succ = getARouteHandler(t2) |
170126
result = succ.backtrack(t2, t)
171127
or
172-
routeHandlerStep(result, succ) and
128+
HTTP::routeHandlerStep(result, succ) and
173129
t = t2
174130
)
175131
}

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

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,51 @@ module HTTP {
233233
ResponseExpr getAResponseExpr() { result.getRouteHandler() = this }
234234
}
235235

236+
/**
237+
* Holds if `call` decorates the function `pred`.
238+
* This means that `call` returns a function that forwards its arguments to `pred`.
239+
* Only holds when the decorator looks like it is decorating a route-handler.
240+
*/
241+
private predicate isDecoratedCall(DataFlow::CallNode call, DataFlow::FunctionNode decoratee) {
242+
// indirect route-handler `result` is given to function `outer`, which returns function `inner` which calls the function `pred`.
243+
exists(int i, Function outer, Function inner |
244+
decoratee = call.getArgument(i).getALocalSource() and
245+
outer = call.getACallee() and
246+
inner = outer.getAReturnedExpr() and
247+
isAForwardingRouteHandlerCall(DataFlow::parameterNode(outer.getParameter(i)), inner.flow())
248+
)
249+
}
250+
251+
/**
252+
* Holds if `f` looks like a route-handler and a call to `callee` inside `f` forwards all of the parameters from `f` to that call,
253+
*/
254+
private predicate isAForwardingRouteHandlerCall(
255+
DataFlow::SourceNode callee, HTTP::RouteHandlerCandidate f
256+
) {
257+
exists(DataFlow::CallNode call | call = callee.getACall() |
258+
forall(int arg | arg = [0 .. f.getNumParameter() - 1] |
259+
f.getParameter(arg).flowsTo(call.getArgument(arg))
260+
) and
261+
call.getContainer() = f.getFunction()
262+
)
263+
}
264+
265+
/**
266+
* Holds if there exists a step from `pred` to `succ` for a RouteHandler - beyond the usual steps defined by TypeTracking.
267+
*/
268+
predicate routeHandlerStep(DataFlow::SourceNode pred, DataFlow::SourceNode succ) {
269+
isDecoratedCall(succ, pred)
270+
or
271+
// A forwarding call
272+
isAForwardingRouteHandlerCall(pred, succ)
273+
or
274+
// a container containing route-handlers.
275+
exists(HTTP::RouteHandlerCandidateContainer container | pred = container.getRouteHandler(succ))
276+
or
277+
// (function (req, res) {}).bind(this);
278+
exists(DataFlow::PartialInvokeNode call | succ = call.getBoundFunction(pred, 0))
279+
}
280+
236281
/**
237282
* An expression that sets up a route on a server.
238283
*/
@@ -596,7 +641,7 @@ module HTTP {
596641
DataFlow::SourceNode getAPossiblyDecoratedHandler(RouteHandlerCandidate candidate) {
597642
result = candidate
598643
or
599-
Express::isDecoratedCall(result, candidate)
644+
isDecoratedCall(result, candidate)
600645
}
601646

602647
/**

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ module NodeJSLib {
232232
result = succ.backtrack(t2, t)
233233
or
234234
t = t2 and
235-
Express::routeHandlerStep(result, succ)
235+
HTTP::routeHandlerStep(result, succ)
236236
)
237237
}
238238

0 commit comments

Comments
 (0)