-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathVulnerability.qll
More file actions
93 lines (78 loc) · 2.91 KB
/
Vulnerability.qll
File metadata and controls
93 lines (78 loc) · 2.91 KB
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import csharp
/**
* A package reference in an XML file, for example in a
* `.csproj` file, a `.props` file, or a `packages.config` file.
*/
class Package extends XMLElement {
string name;
Version version;
Package() {
(this.getName() = "PackageManagement" or this.getName() = "PackageReference") and
name = this.getAttributeValue("Include") and
version = this.getAttributeValue("Version")
or
this.getName() = "package" and
name = this.getAttributeValue("id") and
version = this.getAttributeValue("version")
}
/** Gets the name of the package, for example `System.IO.Pipelines`. */
string getPackageName() { result = name }
/** Gets the version of the package, for example `4.5.1`. */
Version getVersion() { result = version }
override string toString() { result = name + " " + version }
}
/**
* A vulnerability, where the name of the vulnerability is this string.
* One of `matchesRange` or `matchesVersion` must be overridden in order to
* specify which packages are vulnerable.
*/
abstract class Vulnerability extends string {
bindingset[this]
Vulnerability() { any() }
/**
* Holds if a package with name `name` is vulnerable from version `affected`
* until version `fixed`.
*/
predicate matchesRange(string name, Version affected, Version fixed) { none() }
/**
* Holds if a package with name `name` is vulnerable in version `affected`, and
* is fixed by version `fixed`.
*/
predicate matchesVersion(string name, Version affected, Version fixed) { none() }
/** Gets the URL describing the vulnerability. */
abstract string getUrl();
/**
* Holds if a package with name `name` and version `version`
* has this vulnerability. The fixed version is given by `fixed`.
*/
bindingset[name, version]
predicate isVulnerable(string name, Version version, Version fixed) {
exists(Version affected, string n | name.toLowerCase() = n.toLowerCase() |
matchesRange(n, affected, fixed) and
version.compareTo(fixed) < 0 and
version.compareTo(affected) >= 0
or
matchesVersion(n, affected, fixed) and
version.compareTo(affected) = 0
)
}
}
bindingset[name, version]
private Version getUltimateFix(string name, Version version) {
result = max(Version fix | any(Vulnerability v).isVulnerable(name, version, fix))
}
/**
* A package with a vulnerability.
*/
class VulnerablePackage extends Package {
Vulnerability vuln;
VulnerablePackage() { vuln.isVulnerable(this.getPackageName(), this.getVersion(), _) }
/** Gets the vulnerability of this package. */
Vulnerability getVulnerability() { result = vuln }
/** Gets the version of this package where the vulnerability is fixed. */
Version getFixedVersion() {
// This is needed because sometimes the "fixed" version of some
// vulnerabilities are themselves vulnerable to other vulnerabilities.
result = getUltimateFix(this.getPackageName(), this.getVersion())
}
}