Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f3239cb

Browse files
author
Max Schaefer
committed
JavaScript: Respect barriers on return edges.
1 parent 18a74a2 commit f3239cb

4 files changed

Lines changed: 29 additions & 6 deletions

File tree

javascript/ql/src/semmle/javascript/dataflow/Configuration.qll

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -487,11 +487,12 @@ private predicate reachableFromInput(Function f, DataFlow::Node invk,
487487
* configuration `cfg`, possibly through callees.
488488
*/
489489
private predicate flowThroughCall(DataFlow::Node input, DataFlow::Node invk,
490-
DataFlow::Configuration cfg, boolean valuePreserving) {
490+
DataFlow::Configuration cfg, PathSummary summary) {
491491
exists (Function f, DataFlow::ValueNode ret |
492492
ret.asExpr() = f.getAReturnedExpr() and
493493
calls(invk, f) and // Do not consider partial calls
494-
reachableFromInput(f, invk, input, ret, cfg, PathSummary::level(valuePreserving))
494+
reachableFromInput(f, invk, input, ret, cfg, summary) and
495+
not cfg.isBarrier(ret, invk)
495496
)
496497
}
497498

@@ -557,10 +558,7 @@ private predicate flowStep(DataFlow::Node pred, DataFlow::Configuration cfg,
557558
or
558559
// Flow through a function that returns a value that depends on one of its arguments
559560
// or a captured variable
560-
exists (boolean valuePreserving |
561-
flowThroughCall(pred, succ, cfg, valuePreserving) and
562-
summary = PathSummary::level(valuePreserving)
563-
)
561+
flowThroughCall(pred, succ, cfg, summary)
564562
or
565563
// Flow through a property write/read pair
566564
flowThroughProperty(pred, succ, cfg, summary)

javascript/ql/test/library-tests/InterProceduralFlow/DataFlowConfig.qll

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,11 @@ class TestDataFlowConfiguration extends DataFlow::Configuration {
2222
override predicate isBarrier(DataFlow::Node src, DataFlow::Node snk) {
2323
src = src and
2424
snk.asExpr().(PropAccess).getPropertyName() = "notTracked"
25+
or
26+
exists (Function f |
27+
f.getName().matches("%noReturnTracking%") and
28+
src = f.getAReturnedExpr().flow() and
29+
snk.(DataFlow::InvokeNode).getACallee() = f
30+
)
2531
}
2632
}

javascript/ql/test/library-tests/InterProceduralFlow/TaintTracking.ql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ class TestTaintTrackingConfiguration extends TaintTracking::Configuration {
2222
override predicate isSanitizer(DataFlow::Node src, DataFlow::Node snk) {
2323
src = src and
2424
snk.asExpr().(PropAccess).getPropertyName() = "notTracked"
25+
or
26+
exists (Function f |
27+
f.getName().matches("%noReturnTracking%") and
28+
src = f.getAReturnedExpr().flow() and
29+
snk.(DataFlow::InvokeNode).getACallee() = f
30+
)
2531
}
2632
}
2733

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
(function() {
2+
let source1 = "tainted1";
3+
function noReturnTracking1(x) {
4+
return x;
5+
}
6+
let sink1 = noReturnTracking1(source1);
7+
8+
function noReturnTracking2() {
9+
let source2 = "tainted2";
10+
return source2;
11+
}
12+
let sink2 = noReturnTracking2();
13+
});

0 commit comments

Comments
 (0)