Merge pull request #602 from esben-semmle/js/additional-route-handlers-from-context

Approved by xiemaisi
This commit is contained in:
semmle-qlci
2018-12-03 14:31:10 +00:00
committed by GitHub
13 changed files with 99 additions and 19 deletions

View File

@@ -32,9 +32,7 @@ module ConnectExpressShared {
*
* For example, this could be the function `function(req, res, next){...}`.
*/
class RouteHandlerCandidate extends HTTP::RouteHandlerCandidate, DataFlow::FunctionNode {
override Function astNode;
class RouteHandlerCandidate extends HTTP::RouteHandlerCandidate {
RouteHandlerCandidate() {
exists (string request, string response, string next, string error |

View File

@@ -194,26 +194,83 @@ module Hapi {
*/
class RouteSetup extends MethodCallExpr, HTTP::Servers::StandardRouteSetup {
ServerDefinition server;
string methodName;
Expr handler;
RouteSetup() {
server.flowsTo(getReceiver()) and
methodName = getMethodName() and
(methodName = "route" or methodName = "ext")
(
// server.route({ handler: fun })
getMethodName() = "route" and
hasOptionArgument(0, "handler", handler)
or
// server.ext('/', fun)
getMethodName() = "ext" and
handler = getArgument(1)
)
}
override DataFlow::SourceNode getARouteHandler() {
// server.route({ handler: fun })
methodName = "route" and
result.flowsToExpr(any(Expr e | hasOptionArgument(0, "handler", e)))
or
// server.ext('/', fun)
methodName = "ext" and
result.flowsToExpr(getArgument(1))
result.(DataFlow::SourceNode).flowsTo(handler.flow()) or
result.(DataFlow::TrackedNode).flowsTo(handler.flow())
}
Expr getRouteHandlerExpr() {
result = handler
}
override Expr getServer() {
result = server
}
}
/**
* A function that looks like a Hapi route handler.
*
* For example, this could be the function `function(request, h){...}`.
*/
class RouteHandlerCandidate extends HTTP::RouteHandlerCandidate {
RouteHandlerCandidate() {
exists (string request, string responseToolkit |
(request = "request" or request = "req") and
responseToolkit = "h" and
// heuristic: parameter names match the Hapi documentation
astNode.getNumParameter() = 2 and
astNode.getParameter(0).getName() = request and
astNode.getParameter(1).getName() = responseToolkit |
not (
// heuristic: is not invoked (Hapi invokes this at a call site we cannot reason precisely about)
exists(DataFlow::InvokeNode cs | cs.getACallee() = astNode)
)
)
}
}
/**
* Tracking for `RouteHandlerCandidate`.
*/
private class TrackedRouteHandlerCandidate extends DataFlow::TrackedNode {
TrackedRouteHandlerCandidate() {
this instanceof RouteHandlerCandidate
}
}
/**
* A function that looks like a Hapi route handler and flows to a route setup.
*/
private class TrackedRouteHandlerCandidateWithSetup extends RouteHandler, HTTP::Servers::StandardRouteHandler, DataFlow::ValueNode {
override Function astNode;
TrackedRouteHandlerCandidateWithSetup() {
exists(TrackedRouteHandlerCandidate tracked |
tracked.flowsTo(any(RouteSetup s).getRouteHandlerExpr().flow()) and
this = tracked
)
}
}
}

View File

@@ -597,9 +597,7 @@ module NodeJSLib {
*
* For example, this could be the function `function(req, res){...}`.
*/
class RouteHandlerCandidate extends HTTP::RouteHandlerCandidate, DataFlow::FunctionNode {
override Function astNode;
class RouteHandlerCandidate extends HTTP::RouteHandlerCandidate {
RouteHandlerCandidate() {
exists (string request, string response |

View File

@@ -8,7 +8,7 @@ import javascript
private import semmle.javascript.frameworks.ConnectExpressShared
/**
* Adds `NodeJSLib::RouteHandlerCandidate` to the extent of `NodeJSLib::RouteHandler`.
* Add `NodeJSLib::RouteHandlerCandidate` to the extent of `NodeJSLib::RouteHandler`.
*/
private class PromotedNodeJSLibCandidate extends NodeJSLib::RouteHandler, HTTP::Servers::StandardRouteHandler {
@@ -19,7 +19,18 @@ private class PromotedNodeJSLibCandidate extends NodeJSLib::RouteHandler, HTTP::
}
/**
* Adds `ConnectExpressShared::RouteHandlerCandidate` to the extent of `Express::RouteHandler`.
* Add `Hapi::RouteHandlerCandidate` to the extent of `Hapi::RouteHandler`.
*/
private class PromotedHapiCandidate extends Hapi::RouteHandler, HTTP::Servers::StandardRouteHandler {
PromotedHapiCandidate() {
this instanceof Hapi::RouteHandlerCandidate
}
}
/**
* Add `ConnectExpressShared::RouteHandlerCandidate` to the extent of `Express::RouteHandler`.
*/
private class PromotedExpressCandidate extends Express::RouteHandler, HTTP::Servers::StandardRouteHandler {
@@ -34,7 +45,7 @@ private class PromotedExpressCandidate extends Express::RouteHandler, HTTP::Serv
}
/**
* Adds `ConnectExpressShared::RouteHandlerCandidate` to the extent of `Connect::RouteHandler`.
* Add `ConnectExpressShared::RouteHandlerCandidate` to the extent of `Connect::RouteHandler`.
*/
private class PromotedConnectCandidate extends Connect::RouteHandler, HTTP::Servers::StandardRouteHandler {