add a step for referencing instance/static methods on classes

This commit is contained in:
Erik Krogh Kristensen
2021-01-28 13:34:36 +01:00
parent 518bfa4d41
commit 49b1bfc41b
3 changed files with 26 additions and 5 deletions

View File

@@ -54,27 +54,34 @@ module CallGraph {
PreCallGraphStep::step(any(DataFlow::Node n | function.flowsTo(n)), result)
or
imprecision = 0 and
result = callgraphStep(function, t)
}
/**
* Gets a reference to `function` type-tracked by `t`.
* Only considers callgraph specific steps.
*/
cached
DataFlow::SourceNode callgraphStep(DataFlow::FunctionNode function, DataFlow::TypeTracker t) {
exists(DataFlow::ClassNode cls |
exists(string name |
function = cls.getInstanceMethod(name) and
cls.getAnInstanceMemberAccess(name, t.continue()).flowsTo(result)
cls.getAnInstanceMemberAccess(name, t.continue()) = result
or
function = cls.getStaticMethod(name) and
cls.getAClassReference(t.continue()).getAPropertyRead(name).flowsTo(result)
cls.getAClassReference(t.continue()).getAPropertyRead(name) = result
)
or
function = cls.getConstructor() and
cls.getAClassReference(t.continue()).flowsTo(result)
cls.getAClassReference(t.continue()) = result
)
or
imprecision = 0 and
exists(DataFlow::FunctionNode outer |
result = getAFunctionReference(outer, 0, t.continue()).getAnInvocation() and
locallyReturnedFunction(outer, function)
)
}
cached
private predicate locallyReturnedFunction(
DataFlow::FunctionNode outer, DataFlow::FunctionNode inner
) {

View File

@@ -5,6 +5,7 @@
import javascript
private import semmle.javascript.DynamicPropertyAccess
private import semmle.javascript.dataflow.internal.StepSummary
private import semmle.javascript.dataflow.internal.CallGraphs
module HTTP {
/**
@@ -299,6 +300,9 @@ module HTTP {
exists(DataFlow::PartialInvokeNode call |
succ = call.getBoundFunction(any(DataFlow::Node n | pred.flowsTo(n)), 0)
)
or
// references to class methods
succ = CallGraph::callgraphStep(pred, DataFlow::TypeTracker::end())
}
/**

View File

@@ -43,6 +43,8 @@ test_ResponseExpr
| createServer.js:2:35:2:37 | res | createServer.js:2:20:2:41 | functio ... res) {} |
| createServer.js:3:38:3:40 | res | createServer.js:3:23:3:44 | functio ... res) {} |
| createServer.js:4:37:4:39 | res | createServer.js:4:31:4:46 | (req, res) => {} |
| createServer.js:25:52:25:54 | res | createServer.js:25:37:27:5 | functio ... ;\\n } |
| createServer.js:26:9:26:11 | res | createServer.js:25:37:27:5 | functio ... ;\\n } |
| src/http.js:4:46:4:48 | res | src/http.js:4:32:10:1 | functio ... .foo;\\n} |
| src/http.js:7:3:7:5 | res | src/http.js:4:32:10:1 | functio ... .foo;\\n} |
| src/http.js:12:33:12:35 | res | src/http.js:12:19:16:1 | functio ... ar");\\n} |
@@ -142,6 +144,8 @@ test_RouteHandler_getAResponseExpr
| createServer.js:2:20:2:41 | functio ... res) {} | createServer.js:2:35:2:37 | res |
| createServer.js:3:23:3:44 | functio ... res) {} | createServer.js:3:38:3:40 | res |
| createServer.js:4:31:4:46 | (req, res) => {} | createServer.js:4:37:4:39 | res |
| createServer.js:25:37:27:5 | functio ... ;\\n } | createServer.js:25:52:25:54 | res |
| createServer.js:25:37:27:5 | functio ... ;\\n } | createServer.js:26:9:26:11 | res |
| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:4:46:4:48 | res |
| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:7:3:7:5 | res |
| src/http.js:12:19:16:1 | functio ... ar");\\n} | src/http.js:12:33:12:35 | res |
@@ -180,6 +184,7 @@ test_ServerDefinition_getARouteHandler
| createServer.js:2:1:2:42 | https.c ... es) {}) | createServer.js:2:20:2:41 | functio ... res) {} |
| createServer.js:3:1:3:45 | https.c ... es) {}) | createServer.js:3:23:3:44 | functio ... res) {} |
| createServer.js:4:1:4:47 | require ... => {}) | createServer.js:4:31:4:46 | (req, res) => {} |
| createServer.js:31:17:31:58 | http.cr ... dler()) | createServer.js:25:37:27:5 | functio ... ;\\n } |
| src/http.js:4:14:10:2 | http.cr ... foo;\\n}) | src/http.js:4:32:10:1 | functio ... .foo;\\n} |
| src/http.js:12:1:16:2 | http.cr ... r");\\n}) | src/http.js:12:19:16:1 | functio ... ar");\\n} |
| src/http.js:57:1:57:31 | http.cr ... dler()) | src/http.js:55:12:55:30 | function(req,res){} |
@@ -195,6 +200,7 @@ test_ServerDefinition_getARouteHandler
| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:25:24:27:3 | (req, r ... ");\\n } |
| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:28:15:30:3 | functio ... ");\\n } |
test_ResponseSendArgument
| createServer.js:26:17:26:25 | this.data | createServer.js:25:37:27:5 | functio ... ;\\n } |
| src/http.js:14:13:14:17 | "foo" | src/http.js:12:19:16:1 | functio ... ar");\\n} |
| src/http.js:15:11:15:15 | "bar" | src/http.js:12:19:16:1 | functio ... ar");\\n} |
| src/http.js:64:11:64:16 | "bar2" | src/http.js:62:19:65:1 | functio ... r2");\\n} |
@@ -210,6 +216,7 @@ test_RouteSetup_getARouteHandler
| createServer.js:31:17:31:58 | http.cr ... dler()) | createServer.js:22:41:24:5 | return of anonymous function |
| createServer.js:31:17:31:58 | http.cr ... dler()) | createServer.js:23:16:23:33 | this.handleRequest |
| createServer.js:31:17:31:58 | http.cr ... dler()) | createServer.js:23:16:23:44 | this.ha ... d(this) |
| createServer.js:31:17:31:58 | http.cr ... dler()) | createServer.js:25:37:27:5 | functio ... ;\\n } |
| createServer.js:31:17:31:58 | http.cr ... dler()) | createServer.js:31:35:31:57 | app.get ... ndler() |
| src/http.js:4:14:10:2 | http.cr ... foo;\\n}) | src/http.js:4:32:10:1 | functio ... .foo;\\n} |
| src/http.js:12:1:16:2 | http.cr ... r");\\n}) | src/http.js:12:19:16:1 | functio ... ar");\\n} |
@@ -258,6 +265,7 @@ test_RouteHandler
| createServer.js:2:20:2:41 | functio ... res) {} | createServer.js:2:1:2:42 | https.c ... es) {}) |
| createServer.js:3:23:3:44 | functio ... res) {} | createServer.js:3:1:3:45 | https.c ... es) {}) |
| createServer.js:4:31:4:46 | (req, res) => {} | createServer.js:4:1:4:47 | require ... => {}) |
| createServer.js:25:37:27:5 | functio ... ;\\n } | createServer.js:31:17:31:58 | http.cr ... dler()) |
| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:4:14:10:2 | http.cr ... foo;\\n}) |
| src/http.js:12:19:16:1 | functio ... ar");\\n} | src/http.js:12:1:16:2 | http.cr ... r");\\n}) |
| src/http.js:55:12:55:30 | function(req,res){} | src/http.js:57:1:57:31 | http.cr ... dler()) |
@@ -276,6 +284,7 @@ test_RequestExpr
| createServer.js:2:30:2:32 | req | createServer.js:2:20:2:41 | functio ... res) {} |
| createServer.js:3:33:3:35 | req | createServer.js:3:23:3:44 | functio ... res) {} |
| createServer.js:4:32:4:34 | req | createServer.js:4:31:4:46 | (req, res) => {} |
| createServer.js:25:47:25:49 | req | createServer.js:25:37:27:5 | functio ... ;\\n } |
| src/http.js:4:41:4:43 | req | src/http.js:4:32:10:1 | functio ... .foo;\\n} |
| src/http.js:6:26:6:28 | req | src/http.js:4:32:10:1 | functio ... .foo;\\n} |
| src/http.js:8:3:8:5 | req | src/http.js:4:32:10:1 | functio ... .foo;\\n} |
@@ -317,6 +326,7 @@ test_RouteHandler_getARequestExpr
| createServer.js:2:20:2:41 | functio ... res) {} | createServer.js:2:30:2:32 | req |
| createServer.js:3:23:3:44 | functio ... res) {} | createServer.js:3:33:3:35 | req |
| createServer.js:4:31:4:46 | (req, res) => {} | createServer.js:4:32:4:34 | req |
| createServer.js:25:37:27:5 | functio ... ;\\n } | createServer.js:25:47:25:49 | req |
| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:4:41:4:43 | req |
| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:6:26:6:28 | req |
| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:8:3:8:5 | req |