Skip to content

Commit 87696e5

Browse files
committed
Swift: Break the 'taint reach' metric off into its own query (it's expensive to compute).
1 parent ec573bd commit 87696e5

File tree

2 files changed

+48
-30
lines changed

2 files changed

+48
-30
lines changed

swift/ql/src/queries/Summary/SummaryStats.ql

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,32 +9,8 @@
99
import swift
1010
import codeql.swift.dataflow.FlowSources
1111
import codeql.swift.security.SensitiveExprs
12-
import codeql.swift.dataflow.DataFlow
13-
import codeql.swift.dataflow.TaintTracking
1412
import codeql.swift.regex.Regex
1513

16-
/**
17-
* A taint configuration for tainted data reaching any node.
18-
*/
19-
module TaintReachConfig implements DataFlow::ConfigSig {
20-
predicate isSource(DataFlow::Node node) { node instanceof FlowSource }
21-
22-
predicate isSink(DataFlow::Node node) { any() }
23-
}
24-
25-
module TaintReachFlow = TaintTracking::Global<TaintReachConfig>;
26-
27-
/**
28-
* Gets the total number of dataflow nodes that taint reaches (from any source).
29-
*/
30-
int taintedNodesCount() { result = count(DataFlow::Node n | TaintReachFlow::flowTo(n)) }
31-
32-
/**
33-
* Gets the proportion of dataflow nodes that taint reaches (from any source),
34-
* expressed as a count per million nodes.
35-
*/
36-
float taintReach() { result = (taintedNodesCount() * 1000000.0) / count(DataFlow::Node n) }
37-
3814
predicate statistic(string what, string value) {
3915
what = "Files" and value = count(File f).toString()
4016
or
@@ -52,12 +28,6 @@ predicate statistic(string what, string value) {
5228
or
5329
what = "Sensitive expressions" and value = count(SensitiveExpr e).toString()
5430
or
55-
what = "Dataflow nodes (total)" and value = count(DataFlow::Node n).toString()
56-
or
57-
what = "Dataflow nodes (tainted)" and value = taintedNodesCount().toString()
58-
or
59-
what = "Taint reach (per million nodes)" and value = taintReach().toString()
60-
or
6131
what = "Regular expression evals" and value = count(RegexEval e).toString()
6232
or
6333
what = "Regular expression evals with associated regex" and
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
* @name Taint Reach
3+
* @description Calculates 'taint reach', a measure of how much of a database
4+
* is reached from flow sources, via taint flow. This can be
5+
* expensive to compute on large databases.
6+
* @kind table
7+
* @id swift/summary/taint-reach
8+
* @tags summary
9+
*/
10+
11+
import swift
12+
import codeql.swift.dataflow.FlowSources
13+
import codeql.swift.dataflow.DataFlow
14+
import codeql.swift.dataflow.TaintTracking
15+
16+
/**
17+
* A taint configuration for tainted data reaching any node.
18+
*/
19+
module TaintReachConfig implements DataFlow::ConfigSig {
20+
predicate isSource(DataFlow::Node node) { node instanceof FlowSource }
21+
22+
predicate isSink(DataFlow::Node node) { any() }
23+
}
24+
25+
module TaintReachFlow = TaintTracking::Global<TaintReachConfig>;
26+
27+
/**
28+
* Gets the total number of dataflow nodes that taint reaches (from any source).
29+
*/
30+
int taintedNodesCount() { result = count(DataFlow::Node n | TaintReachFlow::flowTo(n)) }
31+
32+
/**
33+
* Gets the proportion of dataflow nodes that taint reaches (from any source),
34+
* expressed as a count per million nodes.
35+
*/
36+
float taintReach() { result = (taintedNodesCount() * 1000000.0) / count(DataFlow::Node n) }
37+
38+
predicate statistic(string what, string value) {
39+
what = "Dataflow nodes (total)" and value = count(DataFlow::Node n).toString()
40+
or
41+
what = "Dataflow nodes (tainted)" and value = taintedNodesCount().toString()
42+
or
43+
what = "Taint reach (per million nodes)" and value = taintReach().toString()
44+
}
45+
46+
from string what, string value
47+
where statistic(what, value)
48+
select what, value

0 commit comments

Comments
 (0)