forked from RedHatProductSecurity/osidb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
models.py
134 lines (107 loc) · 5.53 KB
/
models.py
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
"""
Exploits models
"""
import uuid
from django.db import models
from osidb.models import Affect, Flaw
class Exploit(models.Model):
"""
Model represents combination exploit-CVE. One exploit code can have multiple records,
one for each CVE it impacts. We need to treat it separately, as the exploit maturity may be
different for each CVE. Exploit data are downloaded from multiple sources.
"""
class ExploitSource(models.TextChoices):
"""
Known exploit sources. Correct representative strings or official acronyms are used
to simplify use in future GUI and other outputs for the end user.
"""
CISA = "CISA" # https://www.cisa.gov/
METASPLOIT = "Metasploit" # https://www.metasploit.com/
EXPLOITDB = "Exploit-DB" # https://www.exploit-db.com/
class ExploitMaturity(models.IntegerChoices):
"""
Exploit Code Maturity as defined in CVSS 3.1 Temporal score
Database value CVSS value Explanation
Null X Not Defined
0 U Unproven. No exploit code is available, or an exploit is
theoretical.
1 P Proof-of-concept. Proof-of-concept exploit code is
available, or an attack demonstration is not practical for
most systems. The code or technique is not functional in
all situations and may require substantial modification by
a skilled attacker.
2 F Functional. Functional exploit code is available. The code
works in most situations where the vulnerability exists.
3 H High. Functional autonomous code exists, or no exploit is
required (manual trigger) and details are widely
available. Exploit code works in every situation, or is
actively being delivered via an autonomous agent (such as
a worm or virus). Network-connected systems are likely to
encounter scanning or exploitation attempts. Exploit
development has reached the level of reliable, widely
available, easy-to-use automated tools.
"""
U = 0
P = 1
F = 2
H = 3
# Internal primary key
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
cve = models.CharField(max_length=50)
flaw = models.ForeignKey(Flaw, on_delete=models.SET_NULL, null=True)
source = models.CharField(choices=ExploitSource.choices, max_length=50)
date = models.DateField(null=True) # First available date
# Reference URL to exploit code, cannot be None for the UniqueConstraint to work.
reference = models.CharField(max_length=512, default="N/A")
maturity_preliminary = models.IntegerField(choices=ExploitMaturity.choices)
class Meta:
constraints = [
models.UniqueConstraint(
fields=["cve", "source", "reference"], name="unique_exploit_cve"
),
]
def __str__(self):
return f"{self.cve} {self.source}"
class EPSS(models.Model):
"""
Model represents Exploit Prediction Scoring System (EPSS) data downloaded from
https://www.first.org/epss/data_stats . EPSS is ever-changing, so it is necessary to always
download fresh values.
"""
class Meta:
ordering = ["cve"]
# Internal primary key
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
cve = models.CharField(unique=True, max_length=50)
flaw = models.ForeignKey(Flaw, on_delete=models.SET_NULL, null=True)
epss = models.FloatField()
def __str__(self):
return str(self.flaw)
class ExploitReview(models.Model):
"""
Model represents exploit maturity review with reference to CVE-product-package (flaw-affect).
When exploit data are downloaded the preliminary exploit maturity value is assigned. Review
is a way to modify exploit maturity value, but always with relation to a specific
CVE-product-package combination, represented by flaw-affect.
Apart from this relationship and maturity level, additional data is useful. Namely comment
to store explanation of reviewer decision and possibly partially independent decision if the
specified affect needs to be fixed. The fix decision is dependent on exploit maturity,
but there may be exceptions, e.g. product is not supported anymore, or it is easier to
provide fix then share explanation with customers.
"""
# Internal primary key
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
exploit = models.ForeignKey(Exploit, on_delete=models.PROTECT)
flaw = models.ForeignKey(Flaw, on_delete=models.CASCADE)
affect = models.ForeignKey(Affect, on_delete=models.CASCADE)
maturity_selected = models.IntegerField(null=True)
comment = models.TextField(blank=True)
fix_needed = models.BooleanField(default=True)
def __str__(self):
return str(self.flaw)
class Meta:
constraints = [
models.UniqueConstraint(
fields=["exploit", "flaw", "affect"], name="unique_exploit_review"
),
]