Skip to content

Commit 1fe5a9e

Browse files
authored
Merge pull request #2236 from max-schaefer/js/data-flow-exploration
Approved by erik-krogh, esbena
2 parents 794d5bd + 03c9a40 commit 1fe5a9e

2 files changed

Lines changed: 86 additions & 0 deletions

File tree

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/**
2+
* Provides machinery for performing backward data-flow exploration.
3+
*
4+
* Importing this module effectively makes all data-flow and taint-tracking configurations
5+
* ignore their `isSource` predicate. Instead, flow is tracked from any _initial node_ (that is,
6+
* a node without incoming flow) to a sink node. All initial nodes are then treated as source
7+
* nodes.
8+
*
9+
* Data-flow exploration cannot be used with configurations depending on other configurations.
10+
*
11+
* NOTE: This library should only be used for debugging, not in production code. Backward
12+
* exploration in particular does not scale on non-trivial code bases and hence is of limited
13+
* usefulness as it stands.
14+
*/
15+
16+
import javascript
17+
18+
private class BackwardExploringConfiguration extends DataFlow::Configuration {
19+
DataFlow::Configuration cfg;
20+
21+
BackwardExploringConfiguration() {
22+
this = cfg
23+
}
24+
25+
override predicate isSource(DataFlow::Node node) { any() }
26+
27+
override predicate isSource(DataFlow::Node node, DataFlow::FlowLabel lbl) { any() }
28+
29+
override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) {
30+
exists(DataFlow::PathNode src, DataFlow::PathNode snk | hasFlowPath(src, snk) |
31+
source = src.getNode() and
32+
sink = snk.getNode()
33+
)
34+
}
35+
36+
override predicate hasFlowPath(DataFlow::SourcePathNode source, DataFlow::SinkPathNode sink) {
37+
exists(DataFlow::MidPathNode first |
38+
source.getConfiguration() = this and
39+
source.getASuccessor() = first and
40+
not exists(DataFlow::MidPathNode mid | mid.getASuccessor() = first) and
41+
first.getASuccessor*() = sink
42+
)
43+
}
44+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**
2+
* Provides machinery for performing forward data-flow exploration.
3+
*
4+
* Importing this module effectively makes all data-flow and taint-tracking configurations
5+
* ignore their `isSink` predicate. Instead, flow is tracked from source nodes as far as
6+
* possible, until a _terminal node_ (that is, a node without any outgoing flow) is reached.
7+
* All terminal nodes are then treated as sink nodes.
8+
*
9+
* Data-flow exploration cannot be used with configurations depending on other configurations.
10+
*
11+
* NOTE: This library should only be used for debugging, not in production code.
12+
*/
13+
14+
import javascript
15+
16+
private class ForwardExploringConfiguration extends DataFlow::Configuration {
17+
DataFlow::Configuration cfg;
18+
19+
ForwardExploringConfiguration() {
20+
this = cfg
21+
}
22+
23+
override predicate isSink(DataFlow::Node node) { any() }
24+
25+
override predicate isSink(DataFlow::Node node, DataFlow::FlowLabel lbl) { any() }
26+
27+
override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) {
28+
exists(DataFlow::PathNode src, DataFlow::PathNode snk | hasFlowPath(src, snk) |
29+
source = src.getNode() and
30+
sink = snk.getNode()
31+
)
32+
}
33+
34+
override predicate hasFlowPath(DataFlow::SourcePathNode source, DataFlow::SinkPathNode sink) {
35+
exists(DataFlow::MidPathNode last |
36+
source.getConfiguration() = this and
37+
source.getASuccessor*() = last and
38+
not last.getASuccessor() instanceof DataFlow::MidPathNode and
39+
last.getASuccessor() = sink
40+
)
41+
}
42+
}

0 commit comments

Comments
 (0)