mirror of
https://github.com/github/codeql.git
synced 2026-04-30 03:05:15 +02:00
JavaScript: Respect barriers on return edges.
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
13
javascript/ql/test/library-tests/InterProceduralFlow/tst3.js
Normal file
13
javascript/ql/test/library-tests/InterProceduralFlow/tst3.js
Normal 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();
|
||||
});
|
||||
Reference in New Issue
Block a user