Skip to content

Commit 6749804

Browse files
committed
Fix model relations and patch inference in importers
Signed-off-by: Shivam Sandbhor <shivam.sandbhor@gmail.com>
1 parent 9891b5e commit 6749804

11 files changed

Lines changed: 125 additions & 74 deletions

File tree

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ cached-property==1.5.1
77
cffi==1.14.0
88
contextlib2==0.5.5
99
decorator==4.4.2
10-
univers==21.4.9
10+
univers==21.4.16.6
1111
dj-database-url==0.4.2
1212
Django==3.0.14
1313
django-filter==2.2.0

vulnerabilities/data_source.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -532,9 +532,8 @@ def get_data_from_xml_doc(self, xml_doc: ET.ElementTree, pkg_metadata={}) -> Lis
532532
# connected/linked to an OvalDefinition
533533
vuln_id = definition_data["vuln_id"]
534534
description = definition_data["description"]
535-
affected_purls = set()
536-
safe_purls = set()
537535
references = [Reference(url=url) for url in definition_data["reference_urls"]]
536+
affected_packages_with_patched_package = []
538537
for test_data in definition_data["test_data"]:
539538
for package_name in test_data["package_list"]:
540539
if package_name and len(package_name) >= 50:
@@ -570,12 +569,14 @@ def get_data_from_xml_doc(self, xml_doc: ET.ElementTree, pkg_metadata={}) -> Lis
570569
else:
571570
safe_purls.append(purl)
572571

572+
affected_packages_with_patched_package.extend(
573+
nearest_patched_package(affected_purls, safe_purls),
574+
)
575+
573576
all_adv.append(
574577
Advisory(
575578
summary=description,
576-
affected_packages_with_patched_package=nearest_patched_package(
577-
affected_purls, safe_purls
578-
),
579+
affected_packages_with_patched_package=affected_packages_with_patched_package,
579580
vulnerability_id=vuln_id,
580581
references=references,
581582
)

vulnerabilities/import_runner.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,17 +137,21 @@ def process_advisories(data_source: DataSource) -> None:
137137
vulnerable_package, _ = _get_or_create_package(
138138
aff_pkg_with_patched_pkg.vulnerable_package
139139
)
140+
patched_package = None
140141
if aff_pkg_with_patched_pkg.patched_package:
141142
patched_package, _ = _get_or_create_package(
142143
aff_pkg_with_patched_pkg.patched_package
143144
)
144145

145-
models.PackageRelatedVulnerability.objects.get_or_create(
146+
prv, _ = models.PackageRelatedVulnerability.objects.get_or_create(
146147
vulnerability=vuln,
147-
patched_package=patched_package,
148148
package=vulnerable_package,
149149
)
150150

151+
if patched_package:
152+
prv.patched_package = patched_package
153+
prv.save()
154+
151155
except Exception:
152156
# TODO: store error but continue
153157
logger.error(

vulnerabilities/importers/archlinux.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ def _parse(self, record) -> List[Advisory]:
8989

9090
for cve_id in record["issues"]:
9191
impacted_purls, resolved_purls = [], []
92+
affected_packages_with_patched_package = []
9293
for name in record["packages"]:
9394
impacted_purls.append(
9495
PackageURL(
@@ -108,6 +109,9 @@ def _parse(self, record) -> List[Advisory]:
108109
version=record["fixed"],
109110
)
110111
)
112+
affected_packages_with_patched_package.extend(
113+
nearest_patched_package(impacted_purls, resolved_purls)
114+
)
111115

112116
references = []
113117
references.append(
@@ -134,9 +138,7 @@ def _parse(self, record) -> List[Advisory]:
134138
Advisory(
135139
vulnerability_id=cve_id,
136140
summary="",
137-
affected_packages_with_patched_package=nearest_patched_package(
138-
impacted_purls, resolved_purls
139-
),
141+
affected_packages_with_patched_package=affected_packages_with_patched_package,
140142
references=references,
141143
)
142144
)

vulnerabilities/importers/istio.py

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -162,35 +162,41 @@ def process_file(self, path):
162162
data["release_ranges"]
163163
)
164164

165+
affected_packages_with_patched_package = []
166+
165167
safe_purls_golang = [
166168
PackageURL(type="golang", name="istio", version=version)
167169
for version in safe_pkg_versions
168170
]
169171

170-
safe_purls_github = [
171-
PackageURL(type="github", name="istio", version=version)
172-
for version in safe_pkg_versions
173-
]
174-
safe_purls = safe_purls_github + safe_purls_golang
175-
176172
vuln_purls_golang = [
177173
PackageURL(type="golang", name="istio", version=version)
178174
for version in vuln_pkg_versions
179175
]
180176

177+
affected_packages_with_patched_package.extend(
178+
nearest_patched_package(vuln_purls_golang, safe_purls_golang)
179+
)
180+
181+
safe_purls_github = [
182+
PackageURL(type="github", name="istio", version=version)
183+
for version in safe_pkg_versions
184+
]
185+
181186
vuln_purls_github = [
182187
PackageURL(type="github", name="istio", version=version)
183188
for version in vuln_pkg_versions
184189
]
185-
vuln_purls = vuln_purls_github + vuln_purls_golang
190+
191+
affected_packages_with_patched_package.extend(
192+
nearest_patched_package(vuln_purls_github, safe_purls_github)
193+
)
186194

187195
advisories.append(
188196
Advisory(
189197
vulnerability_id=cve_id,
190198
summary=data["description"],
191-
affected_packages_with_patched_package=nearest_patched_package(
192-
vuln_purls, safe_purls
193-
),
199+
affected_packages_with_patched_package=affected_packages_with_patched_package,
194200
)
195201
)
196202

vulnerabilities/importers/kaybee.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ def yaml_file_to_advisory(yaml_path):
5858
package = PackageURL.from_string(entry["id"])
5959
if entry["affected"]:
6060
impacted_packages.append(package)
61-
6261
else:
6362
resolved_packages.append(package)
6463

vulnerabilities/importers/retiredotnet.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
from vulnerabilities.data_source import GitDataSource
3131
from vulnerabilities.data_source import Advisory
3232
from vulnerabilities.data_source import Reference
33-
from vulnerabilities.helpers import nearest_patched_package
33+
from vulnerabilities.helpers import AffectedPackageWithPatchedPackage
3434

3535

3636
class RetireDotnetDataSource(GitDataSource):
@@ -77,16 +77,19 @@ def process_file(self, path) -> List[Advisory]:
7777
else:
7878
return
7979

80-
affected_purls = []
81-
fixed_purls = []
82-
80+
affected_packages_with_patched_package = []
8381
for pkg in json_doc["packages"]:
84-
affected_purls.append(
85-
PackageURL(name=pkg["id"], version=pkg["affected"], type="nuget")
82+
affected_packages_with_patched_package.append(
83+
AffectedPackageWithPatchedPackage(
84+
vulnerable_package=PackageURL(
85+
name=pkg["id"], version=pkg["affected"], type="nuget"
86+
),
87+
patched_package=PackageURL(
88+
name=pkg["id"], version=pkg["fix"], type="nuget"
89+
),
90+
)
8691
)
8792

88-
fixed_purls.append(PackageURL(name=pkg["id"], version=pkg["fix"], type="nuget"))
89-
9093
vuln_reference = [
9194
Reference(
9295
url=json_doc["link"],
@@ -96,8 +99,6 @@ def process_file(self, path) -> List[Advisory]:
9699
return Advisory(
97100
vulnerability_id=vuln_id,
98101
summary=json_doc["description"],
99-
affected_packages_with_patched_package=nearest_patched_package(
100-
affected_purls, fixed_purls
101-
),
102+
affected_packages_with_patched_package=affected_packages_with_patched_package,
102103
references=vuln_reference,
103104
)

vulnerabilities/models.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,11 @@ def generate_vulcoid(timestamp=None):
7474

7575
@property
7676
def vulnerable_to(self):
77-
return self.package_set.filter(
78-
packagerelatedvulnerability__is_vulnerable=True,
79-
)
77+
return self.vulnerable_packages.all()
8078

8179
@property
8280
def resolved_to(self):
83-
return self.package_set.filter(
84-
packagerelatedvulnerability__is_vulnerable=False,
85-
)
81+
return self.patched_packages.all()
8682

8783
def __str__(self):
8884
return self.vulnerability_id or self.summary
@@ -124,19 +120,23 @@ class Package(PackageURLMixin):
124120
to="Vulnerability",
125121
through="PackageRelatedVulnerability",
126122
through_fields=("package", "vulnerability"),
123+
related_name="vulnerable_packages",
124+
)
125+
126+
resolved_vulnerabilities = models.ManyToManyField(
127+
to="Vulnerability",
128+
through="PackageRelatedVulnerability",
129+
through_fields=("patched_package", "vulnerability"),
130+
related_name="patched_packages",
127131
)
128132

129133
@property
130134
def vulnerable_to(self):
131-
return self.vulnerabilities.filter(
132-
packagerelatedvulnerability__package=self,
133-
)
135+
return self.vulnerabilities.all()
134136

135137
@property
136138
def resolved_to(self):
137-
return Vulnerability.objects.filter(
138-
packagerelatedvulnerability__patched_package=self,
139-
)
139+
return self.resolved_vulnerabilities.all()
140140

141141
class Meta:
142142
unique_together = ("name", "namespace", "type", "version", "qualifiers", "subpath")

vulnerabilities/tests/test_archlinux.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,12 @@ def test_import(self):
6363
runner.run()
6464
assert models.Vulnerability.objects.count() == 6
6565
assert models.VulnerabilityReference.objects.count() == 10
66-
assert models.PackageRelatedVulnerability.objects.filter(is_vulnerable=True).count() == 12
67-
assert models.PackageRelatedVulnerability.objects.filter(is_vulnerable=False).count() == 8
66+
assert models.PackageRelatedVulnerability.objects.all().count() == 12
67+
assert (
68+
models.PackageRelatedVulnerability.objects.filter(patched_package__isnull=False).count()
69+
== 8
70+
)
71+
print(models.Package.objects.all())
6872
assert models.Package.objects.count() == 10
6973

7074
self.assert_for_package(

vulnerabilities/tests/test_istio.py

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ def test_process_file(self):
8585
affected_packages_with_patched_package=[
8686
AffectedPackageWithPatchedPackage(
8787
vulnerable_package=PackageURL(
88-
type="github",
88+
type="golang",
8989
name="istio",
9090
version="1.1.0",
9191
),
@@ -99,7 +99,7 @@ def test_process_file(self):
9999
vulnerable_package=PackageURL(
100100
type="golang",
101101
name="istio",
102-
version="1.1.0",
102+
version="1.1.1",
103103
),
104104
patched_package=PackageURL(
105105
type="golang",
@@ -109,96 +109,96 @@ def test_process_file(self):
109109
),
110110
AffectedPackageWithPatchedPackage(
111111
vulnerable_package=PackageURL(
112-
type="github",
112+
type="golang",
113113
name="istio",
114-
version="1.1.1",
114+
version="1.2.1",
115115
),
116116
patched_package=PackageURL(
117117
type="golang",
118118
name="istio",
119-
version="1.1.17",
119+
version="1.2.7",
120120
),
121121
),
122122
AffectedPackageWithPatchedPackage(
123123
vulnerable_package=PackageURL(
124124
type="golang",
125125
name="istio",
126-
version="1.1.1",
126+
version="1.3.0",
127127
),
128128
patched_package=PackageURL(
129129
type="golang",
130130
name="istio",
131-
version="1.1.17",
131+
version="1.3.2",
132132
),
133133
),
134134
AffectedPackageWithPatchedPackage(
135135
vulnerable_package=PackageURL(
136-
type="github",
136+
type="golang",
137137
name="istio",
138-
version="1.2.1",
138+
version="1.3.1",
139139
),
140140
patched_package=PackageURL(
141141
type="golang",
142142
name="istio",
143-
version="1.2.7",
143+
version="1.3.2",
144144
),
145145
),
146146
AffectedPackageWithPatchedPackage(
147147
vulnerable_package=PackageURL(
148-
type="golang",
148+
type="github",
149149
name="istio",
150-
version="1.2.1",
150+
version="1.1.0",
151151
),
152152
patched_package=PackageURL(
153-
type="golang",
153+
type="github",
154154
name="istio",
155-
version="1.2.7",
155+
version="1.1.17",
156156
),
157157
),
158158
AffectedPackageWithPatchedPackage(
159159
vulnerable_package=PackageURL(
160160
type="github",
161161
name="istio",
162-
version="1.3.0",
162+
version="1.1.1",
163163
),
164164
patched_package=PackageURL(
165-
type="golang",
165+
type="github",
166166
name="istio",
167-
version="1.3.2",
167+
version="1.1.17",
168168
),
169169
),
170170
AffectedPackageWithPatchedPackage(
171171
vulnerable_package=PackageURL(
172-
type="golang",
172+
type="github",
173173
name="istio",
174-
version="1.3.0",
174+
version="1.2.1",
175175
),
176176
patched_package=PackageURL(
177-
type="golang",
177+
type="github",
178178
name="istio",
179-
version="1.3.2",
179+
version="1.2.7",
180180
),
181181
),
182182
AffectedPackageWithPatchedPackage(
183183
vulnerable_package=PackageURL(
184184
type="github",
185185
name="istio",
186-
version="1.3.1",
186+
version="1.3.0",
187187
),
188188
patched_package=PackageURL(
189-
type="golang",
189+
type="github",
190190
name="istio",
191191
version="1.3.2",
192192
),
193193
),
194194
AffectedPackageWithPatchedPackage(
195195
vulnerable_package=PackageURL(
196-
type="golang",
196+
type="github",
197197
name="istio",
198198
version="1.3.1",
199199
),
200200
patched_package=PackageURL(
201-
type="golang",
201+
type="github",
202202
name="istio",
203203
version="1.3.2",
204204
),

0 commit comments

Comments
 (0)