JavaScript: Respect barriers on return edges.

This commit is contained in:
Max Schaefer
2018-08-29 15:36:11 +01:00
parent 18a74a2163
commit f3239cbec9
4 changed files with 29 additions and 6 deletions

View File

@@ -487,11 +487,12 @@ private predicate reachableFromInput(Function f, DataFlow::Node invk,
* configuration `cfg`, possibly through callees.
*/
private predicate flowThroughCall(DataFlow::Node input, DataFlow::Node invk,
DataFlow::Configuration cfg, boolean valuePreserving) {
DataFlow::Configuration cfg, PathSummary summary) {
exists (Function f, DataFlow::ValueNode ret |
ret.asExpr() = f.getAReturnedExpr() and
calls(invk, f) and // Do not consider partial calls
reachableFromInput(f, invk, input, ret, cfg, PathSummary::level(valuePreserving))
reachableFromInput(f, invk, input, ret, cfg, summary) and
not cfg.isBarrier(ret, invk)
)
}
@@ -557,10 +558,7 @@ private predicate flowStep(DataFlow::Node pred, DataFlow::Configuration cfg,
or
// Flow through a function that returns a value that depends on one of its arguments
// or a captured variable
exists (boolean valuePreserving |
flowThroughCall(pred, succ, cfg, valuePreserving) and
summary = PathSummary::level(valuePreserving)
)
flowThroughCall(pred, succ, cfg, summary)
or
// Flow through a property write/read pair
flowThroughProperty(pred, succ, cfg, summary)

View File

@@ -22,5 +22,11 @@ class TestDataFlowConfiguration extends DataFlow::Configuration {
override predicate isBarrier(DataFlow::Node src, DataFlow::Node snk) {
src = src and
snk.asExpr().(PropAccess).getPropertyName() = "notTracked"
or
exists (Function f |
f.getName().matches("%noReturnTracking%") and
src = f.getAReturnedExpr().flow() and
snk.(DataFlow::InvokeNode).getACallee() = f
)
}
}

View File

@@ -22,6 +22,12 @@ class TestTaintTrackingConfiguration extends TaintTracking::Configuration {
override predicate isSanitizer(DataFlow::Node src, DataFlow::Node snk) {
src = src and
snk.asExpr().(PropAccess).getPropertyName() = "notTracked"
or
exists (Function f |
f.getName().matches("%noReturnTracking%") and
src = f.getAReturnedExpr().flow() and
snk.(DataFlow::InvokeNode).getACallee() = f
)
}
}

View File

@@ -0,0 +1,13 @@
(function() {
let source1 = "tainted1";
function noReturnTracking1(x) {
return x;
}
let sink1 = noReturnTracking1(source1);
function noReturnTracking2() {
let source2 = "tainted2";
return source2;
}
let sink2 = noReturnTracking2();
});