-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
Copy pathTaintReach.ql
48 lines (40 loc) · 1.5 KB
/
TaintReach.ql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/**
* @name Taint Reach
* @description Calculates 'taint reach', a measure of how much of a database
* is reached from flow sources, via taint flow. This can be
* expensive to compute on large databases.
* @kind table
* @id swift/summary/taint-reach
* @tags summary
*/
import swift
import codeql.swift.dataflow.FlowSources
import codeql.swift.dataflow.DataFlow
import codeql.swift.dataflow.TaintTracking
/**
* A taint configuration for tainted data reaching any node.
*/
module TaintReachConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) { node instanceof FlowSource }
predicate isSink(DataFlow::Node node) { any() }
}
module TaintReachFlow = TaintTracking::Global<TaintReachConfig>;
/**
* Gets the total number of dataflow nodes that taint reaches (from any source).
*/
int taintedNodesCount() { result = count(DataFlow::Node n | TaintReachFlow::flowTo(n)) }
/**
* Gets the proportion of dataflow nodes that taint reaches (from any source),
* expressed as a count per million nodes.
*/
float taintReach() { result = (taintedNodesCount() * 1000000.0) / count(DataFlow::Node n) }
predicate statistic(string what, string value) {
what = "Dataflow nodes (total)" and value = count(DataFlow::Node n).toString()
or
what = "Dataflow nodes (tainted)" and value = taintedNodesCount().toString()
or
what = "Taint reach (per million nodes)" and value = taintReach().toString()
}
from string what, string value
where statistic(what, value)
select what, value