JS: Summarize steps into captured variables

This commit is contained in:
Asger Feldthaus
2021-07-02 13:42:42 +02:00
parent 093ff41170
commit 457ce14ca6
4 changed files with 27 additions and 0 deletions

View File

@@ -1183,6 +1183,13 @@ private predicate flowThroughCall(
not cfg.isLabeledBarrier(output, summary.getEndLabel())
)
or
exists(Function f, LocalVariable variable |
reachableFromInput(f, _, input, output, cfg, summary) and
output = DataFlow::capturedVariableNode(variable) and
getCapturedVariableDepth(variable) < getContainerDepth(f) and // Only step outwards
not cfg.isLabeledBarrier(output, summary.getEndLabel())
)
or
exists(Function f, DataFlow::Node invk, DataFlow::Node ret |
DataFlow::exceptionalFunctionReturnNode(ret, f) and
DataFlow::exceptionalInvocationReturnNode(output, invk.asExpr()) and

View File

@@ -109,6 +109,22 @@ DataFlow::Node getThrowTarget(DataFlow::Node thrower) {
*/
cached
private module CachedSteps {
/** Gets the nesting depth of the given container, starting with the top-level at 0. */
cached
int getContainerDepth(StmtContainer container) {
not exists(container.getEnclosingContainer()) and
result = 0
or
result = 1 + getContainerDepth(container.getEnclosingContainer())
}
/** Gets the nesting depth of the container declaring the given captured variable. */
cached
int getCapturedVariableDepth(LocalVariable v) {
v.isCaptured() and
result = getContainerDepth(v.getDeclaringContainer())
}
/**
* Holds if `f` captures the given `variable` in `cap`.
*/

View File

@@ -33,6 +33,8 @@ typeInferenceMismatch
| callbacks.js:50:18:50:25 | source() | callbacks.js:30:29:30:29 | y |
| callbacks.js:51:18:51:25 | source() | callbacks.js:30:29:30:29 | y |
| callbacks.js:53:23:53:30 | source() | callbacks.js:58:10:58:10 | x |
| capture-flow.js:9:11:9:18 | source() | capture-flow.js:14:10:14:16 | outer() |
| capture-flow.js:9:11:9:18 | source() | capture-flow.js:19:6:19:16 | outerMost() |
| capture-flow.js:31:14:31:21 | source() | capture-flow.js:31:6:31:22 | confuse(source()) |
| captured-sanitizer.js:25:3:25:10 | source() | captured-sanitizer.js:15:10:15:10 | x |
| closure.js:6:15:6:22 | source() | closure.js:8:8:8:31 | string. ... (taint) |

View File

@@ -23,6 +23,8 @@
| callbacks.js:50:18:50:25 | source() | callbacks.js:30:29:30:29 | y |
| callbacks.js:51:18:51:25 | source() | callbacks.js:30:29:30:29 | y |
| callbacks.js:53:23:53:30 | source() | callbacks.js:58:10:58:10 | x |
| capture-flow.js:9:11:9:18 | source() | capture-flow.js:14:10:14:16 | outer() |
| capture-flow.js:9:11:9:18 | source() | capture-flow.js:19:6:19:16 | outerMost() |
| capture-flow.js:31:14:31:21 | source() | capture-flow.js:31:6:31:22 | confuse(source()) |
| captured-sanitizer.js:25:3:25:10 | source() | captured-sanitizer.js:15:10:15:10 | x |
| constructor-calls.js:4:18:4:25 | source() | constructor-calls.js:18:8:18:14 | c.taint |