Skip to content

Commit 16cb2f0

Browse files
committed
Use new severity model for risk calculation
Signed-off-by: Keshav Priyadarshi <[email protected]>
1 parent 287c834 commit 16cb2f0

File tree

3 files changed

+26
-56
lines changed

3 files changed

+26
-56
lines changed

vulnerabilities/migrations/0075_alter_vulnerabilityseverity_options_and_more.py renamed to vulnerabilities/migrations/0077_alter_vulnerabilityseverity_options_and_more.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ def reverse_populate_vulnerability_model_with_severities(apps, schema_editor):
153153
pass
154154

155155
dependencies = [
156-
("vulnerabilities", "0074_update_pysec_advisory_created_by"),
156+
("vulnerabilities", "0076_alter_packagechangelog_software_version_and_more"),
157157
]
158158

159159
operations = [

vulnerabilities/risk.py

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,6 @@
1010

1111
from urllib.parse import urlparse
1212

13-
from vulnerabilities.models import AffectedByPackageRelatedVulnerability
14-
from vulnerabilities.models import Exploit
15-
from vulnerabilities.models import Package
16-
from vulnerabilities.models import Vulnerability
1713
from vulnerabilities.models import VulnerabilityReference
1814
from vulnerabilities.severity_systems import EPSS
1915
from vulnerabilities.weight_config import WEIGHT_CONFIG
@@ -40,7 +36,7 @@ def get_weighted_severity(severities):
4036

4137
score_list = []
4238
for severity in severities:
43-
parsed_url = urlparse(severity.reference.url)
39+
parsed_url = urlparse(severity.url)
4440
severity_source = parsed_url.netloc.replace("www.", "", 1)
4541
weight = WEIGHT_CONFIG.get(severity_source, DEFAULT_WEIGHT)
4642
max_weight = float(weight) / 10
@@ -90,34 +86,32 @@ def get_exploitability_level(exploits, references, severities):
9086
return exploit_level
9187

9288

93-
def compute_vulnerability_risk(vulnerability: Vulnerability):
89+
def compute_vulnerability_risk(vulnerability):
9490
"""
9591
Risk may be expressed as a number ranging from 0 to 10.
9692
Risk is calculated from weighted severity and exploitability values.
9793
It is the maximum value of (the weighted severity multiplied by its exploitability) or 10
9894
9995
Risk = min(weighted severity * exploitability, 10)
10096
"""
101-
references = vulnerability.references
102-
severities = vulnerability.severities.select_related("reference")
103-
exploits = Exploit.objects.filter(vulnerability=vulnerability)
104-
if references.exists() or severities.exists() or exploits.exists():
97+
severities = vulnerability.severities.all()
98+
exploits = vulnerability.exploits.all()
99+
reference = vulnerability.references.all()
100+
if reference.exists() or severities.exists() or exploits.exists():
105101
weighted_severity = get_weighted_severity(severities)
106-
exploitability = get_exploitability_level(exploits, references, severities)
102+
exploitability = get_exploitability_level(exploits, reference, severities)
107103
return min(weighted_severity * exploitability, 10)
108104

109105

110-
def compute_package_risk(package: Package):
106+
def compute_package_risk(package):
111107
"""
112108
Calculate the risk for a package by iterating over all vulnerabilities that affects this package
113109
and determining the associated risk.
114110
"""
115111

116112
result = []
117-
for pkg_related_vul in AffectedByPackageRelatedVulnerability.objects.filter(
118-
package=package
119-
).prefetch_related("vulnerability"):
120-
if risk := compute_vulnerability_risk(pkg_related_vul.vulnerability):
113+
for package_vulnerability in package.affectedbypackagerelatedvulnerability_set.all():
114+
if risk := compute_vulnerability_risk(package_vulnerability.vulnerability):
121115
result.append(risk)
122116

123117
if not result:

vulnerabilities/tests/test_risk.py

Lines changed: 15 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -29,25 +29,20 @@ def vulnerability():
2929
vul = Vulnerability(vulnerability_id="VCID-Existing")
3030
vul.save()
3131

32-
reference1 = VulnerabilityReference.objects.create(
33-
reference_id="",
32+
severity1 = VulnerabilitySeverity.objects.create(
3433
url="https://nvd.nist.gov/vuln/detail/CVE-xxxx-xxx1",
35-
)
36-
37-
VulnerabilitySeverity.objects.create(
38-
reference=reference1,
3934
scoring_system=CVSSV3.identifier,
4035
scoring_elements="CVSS:3.0/AV:P/AC:H/PR:H/UI:R/S:C/C:H/I:H/A:N/E:H/RL:O/RC:R/CR:H/MAC:H/MC:L",
4136
value="6.5",
4237
)
4338

44-
VulnerabilitySeverity.objects.create(
45-
reference=reference1,
39+
severity2 = VulnerabilitySeverity.objects.create(
40+
url="https://nvd.nist.gov/vuln/detail/CVE-xxxx-xxx1",
4641
scoring_system=GENERIC.identifier,
4742
value="MODERATE", # 6.9
4843
)
49-
50-
VulnerabilityRelatedReference.objects.create(reference=reference1, vulnerability=vul)
44+
vul.severities.add(severity1)
45+
vul.severities.add(severity2)
5146

5247
weaknesses = Weakness.objects.create(cwe_id=119)
5348
vul.weaknesses.add(weaknesses)
@@ -84,18 +79,13 @@ def high_epss_score():
8479
vul = Vulnerability(vulnerability_id="VCID-HIGH-EPSS")
8580
vul.save()
8681

87-
reference1 = VulnerabilityReference.objects.create(
88-
reference_id="",
82+
severity = VulnerabilitySeverity.objects.create(
8983
url="https://nvd.nist.gov/vuln/detail/CVE-xxxx-xxx3",
90-
)
91-
92-
VulnerabilitySeverity.objects.create(
93-
reference=reference1,
9484
scoring_system=EPSS.identifier,
9585
value=".9",
9686
)
87+
vul.severities.add(severity)
9788

98-
VulnerabilityRelatedReference.objects.create(reference=reference1, vulnerability=vul)
9989
return vul.severities
10090

10191

@@ -105,28 +95,19 @@ def low_epss_score():
10595
vul = Vulnerability(vulnerability_id="VCID-LOW-EPSS")
10696
vul.save()
10797

108-
reference1 = VulnerabilityReference.objects.create(
109-
reference_id="",
98+
severity = VulnerabilitySeverity.objects.create(
11099
url="https://nvd.nist.gov/vuln/detail/CVE-xxxx-xxx4",
111-
)
112-
113-
VulnerabilitySeverity.objects.create(
114-
reference=reference1,
115100
scoring_system=EPSS.identifier,
116101
value=".3",
117102
)
103+
vul.severities.add(severity)
118104

119-
VulnerabilityRelatedReference.objects.create(reference=reference1, vulnerability=vul)
120105
return vul.severities
121106

122107

123108
@pytest.mark.django_db
124109
def test_exploitability_level(
125-
exploit,
126-
vulnerability_with_exploit_ref,
127-
high_epss_score,
128-
low_epss_score,
129-
vulnerability,
110+
exploit, vulnerability_with_exploit_ref, high_epss_score, low_epss_score
130111
):
131112

132113
assert get_exploitability_level(exploit, None, None) == 2
@@ -137,9 +118,9 @@ def test_exploitability_level(
137118

138119
assert (
139120
get_exploitability_level(
140-
None,
141-
vulnerability_with_exploit_ref.references,
142-
vulnerability_with_exploit_ref.severities,
121+
exploits=None,
122+
references=vulnerability_with_exploit_ref.references.all(),
123+
severities=vulnerability_with_exploit_ref.severities.all(),
143124
)
144125
== 1
145126
)
@@ -152,18 +133,13 @@ def test_get_weighted_severity(vulnerability):
152133
severities = vulnerability.severities.all()
153134
assert get_weighted_severity(severities) == 6.210000000000001
154135

155-
reference2 = VulnerabilityReference.objects.create(
156-
reference_id="",
136+
severity2 = VulnerabilitySeverity.objects.create(
157137
url="https://security-tracker.debian.org/tracker/CVE-2019-13057",
158-
)
159-
160-
VulnerabilitySeverity.objects.create(
161-
reference=reference2,
162138
scoring_system=GENERIC.identifier,
163139
value="CRITICAL",
164140
)
141+
vulnerability.severities.add(severity2)
165142

166-
VulnerabilityRelatedReference.objects.create(reference=reference2, vulnerability=vulnerability)
167143
new_severities = vulnerability.severities.all()
168144
assert get_weighted_severity(new_severities) == 7
169145

0 commit comments

Comments
 (0)