Skip to content

Commit cc91f09

Browse files
committed
Improve the process for importing affected and fixed commits
Signed-off-by: ziad hany <ziadhany2016@gmail.com>
1 parent 9c18571 commit cc91f09

File tree

12 files changed

+2027
-1866
lines changed

12 files changed

+2027
-1866
lines changed

vulnerabilities/importer.py

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -402,18 +402,25 @@ class AffectedPackageV2:
402402
"""
403403
Relate a Package URL with a range of affected versions and fixed versions.
404404
The Package URL must *not* have a version.
405-
AffectedPackage must contain either ``affected_version_range`` or ``fixed_version_range``.
405+
AffectedPackage must contain either ``affected_version_range`` or ``fixed_version_range`` or ``affected_by_commits`` or ``fixed_by_commits``.
406406
"""
407407

408408
package: PackageURL
409409
affected_version_range: Optional[VersionRange] = None
410410
fixed_version_range: Optional[VersionRange] = None
411+
fixed_by_commits: List[CodeCommitData] = dataclasses.field(default_factory=list)
412+
affected_by_commits: List[CodeCommitData] = dataclasses.field(default_factory=list)
411413

412414
def __post_init__(self):
413415
if self.package.version:
414416
raise ValueError(f"Affected Package URL {self.package!r} cannot have a version.")
415417

416-
if not (self.affected_version_range or self.fixed_version_range):
418+
if not (
419+
self.affected_version_range
420+
or self.fixed_version_range
421+
or self.affected_by_commits
422+
or self.fixed_by_commits
423+
):
417424
raise ValueError(
418425
f"Affected Package {self.package!r} should have either fixed version range or an "
419426
"affected version range."
@@ -430,6 +437,8 @@ def _cmp_key(self):
430437
str(self.package),
431438
str(self.affected_version_range or ""),
432439
str(self.fixed_version_range or ""),
440+
str(self.affected_by_commits or []),
441+
str(self.fixed_by_commits or []),
433442
)
434443

435444
def to_dict(self):
@@ -443,6 +452,12 @@ def to_dict(self):
443452
"package": purl_to_dict(self.package),
444453
"affected_version_range": affected_version_range,
445454
"fixed_version_range": fixed_version_range,
455+
"affected_by_commits": [
456+
affected_by_commit.to_dict() for affected_by_commit in self.affected_by_commits
457+
],
458+
"fixed_by_commits": [
459+
fixed_by_commit.to_dict() for fixed_by_commit in self.fixed_by_commits
460+
],
446461
}
447462

448463
@classmethod
@@ -454,6 +469,8 @@ def from_dict(cls, affected_pkg: dict):
454469
fixed_version_range = None
455470
affected_range = affected_pkg["affected_version_range"]
456471
fixed_range = affected_pkg["fixed_version_range"]
472+
affected_by_commits = affected_pkg.get("affected_by_commits") or []
473+
fixed_by_commits = affected_pkg.get("fixed_by_commits") or []
457474

458475
try:
459476
affected_version_range = VersionRange.from_string(affected_range)
@@ -475,6 +492,13 @@ def from_dict(cls, affected_pkg: dict):
475492
package=package,
476493
affected_version_range=affected_version_range,
477494
fixed_version_range=fixed_version_range,
495+
affected_by_commits=[
496+
CodeCommitData.from_dict(affected_by_commit)
497+
for affected_by_commit in affected_by_commits
498+
],
499+
fixed_by_commits=[
500+
CodeCommitData.from_dict(fixed_by_commit) for fixed_by_commit in fixed_by_commits
501+
],
478502
)
479503

480504

@@ -502,8 +526,6 @@ class AdvisoryData:
502526
date_published: Optional[datetime.datetime] = None
503527
weaknesses: List[int] = dataclasses.field(default_factory=list)
504528
severities: List[VulnerabilitySeverity] = dataclasses.field(default_factory=list)
505-
fixed_by_commits: List[CodeCommitData] = dataclasses.field(default_factory=list)
506-
affected_by_commits: List[CodeCommitData] = dataclasses.field(default_factory=list)
507529
url: Optional[str] = None
508530
original_advisory_text: Optional[str] = None
509531

@@ -536,12 +558,6 @@ def to_dict(self):
536558
"severities": [sev.to_dict() for sev in self.severities],
537559
"date_published": self.date_published.isoformat() if self.date_published else None,
538560
"weaknesses": self.weaknesses,
539-
"affected_by_commits": [
540-
affected_by_commit.to_dict() for affected_by_commit in self.affected_by_commits
541-
],
542-
"fixed_by_commits": [
543-
fixed_by_commit.to_dict() for fixed_by_commit in self.fixed_by_commits
544-
],
545561
"url": self.url if self.url else "",
546562
}
547563
return {
@@ -602,8 +618,6 @@ class AdvisoryDataV2:
602618
date_published: Optional[datetime.datetime] = None
603619
weaknesses: List[int] = dataclasses.field(default_factory=list)
604620
url: Optional[str] = None
605-
fixed_by_commits: List[CodeCommitData] = dataclasses.field(default_factory=list)
606-
affected_by_commits: List[CodeCommitData] = dataclasses.field(default_factory=list)
607621

608622
def __post_init__(self):
609623
if self.date_published and not self.date_published.tzinfo:
@@ -627,12 +641,6 @@ def to_dict(self):
627641
"references": [ref.to_dict() for ref in self.references],
628642
"date_published": self.date_published.isoformat() if self.date_published else None,
629643
"weaknesses": self.weaknesses,
630-
"affected_by_commits": [
631-
affected_by_commit.to_dict() for affected_by_commit in self.affected_by_commits
632-
],
633-
"fixed_by_commits": [
634-
fixed_by_commit.to_dict() for fixed_by_commit in self.fixed_by_commits
635-
],
636644
"url": self.url if self.url else "",
637645
}
638646

@@ -652,14 +660,6 @@ def from_dict(cls, advisory_data):
652660
if date_published
653661
else None,
654662
"weaknesses": advisory_data["weaknesses"],
655-
"affected_by_commits": [
656-
CodeCommitData.from_dict(affected_by_commit)
657-
for affected_by_commit in advisory_data["affected_by_commits"]
658-
],
659-
"fixed_by_commits": [
660-
CodeCommitData.from_dict(fixed_by_commit)
661-
for fixed_by_commit in advisory_data["fixed_by_commits"]
662-
],
663663
"url": advisory_data.get("url") or None,
664664
}
665665
return cls(**transformed)

vulnerabilities/importers/curl.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ def parse_advisory_data(raw_data) -> AdvisoryData:
9797
... ]
9898
... }
9999
>>> parse_advisory_data(raw_data)
100-
AdvisoryData(advisory_id='', aliases=['CVE-2024-2379'], summary='QUIC certificate check bypass with wolfSSL', affected_packages=[AffectedPackage(package=PackageURL(type='generic', namespace='curl.se', name='curl', version=None, qualifiers={}, subpath=None), affected_version_range=GenericVersionRange(constraints=(VersionConstraint(comparator='=', version=SemverVersion(string='8.6.0')),)), fixed_version=SemverVersion(string='8.7.0'))], references=[Reference(reference_id='', reference_type='', url='https://curl.se/docs/CVE-2024-2379.html', severities=[VulnerabilitySeverity(system=Cvssv3ScoringSystem(identifier='cvssv3.1', name='CVSSv3.1 Base Score', url='https://www.first.org/cvss/v3-1/', notes='CVSSv3.1 base score and vector'), value='Low', scoring_elements='', published_at=None, url=None)]), Reference(reference_id='', reference_type='', url='https://hackerone.com/reports/2410774', severities=[])], references_v2=[], date_published=datetime.datetime(2024, 3, 27, 8, 0, tzinfo=datetime.timezone.utc), weaknesses=[297], severities=[], fixed_by_commits=[], affected_by_commits=[], url='https://curl.se/docs/CVE-2024-2379.json', original_advisory_text=None)
100+
AdvisoryData(advisory_id='', aliases=['CVE-2024-2379'], summary='QUIC certificate check bypass with wolfSSL', affected_packages=[AffectedPackage(package=PackageURL(type='generic', namespace='curl.se', name='curl', version=None, qualifiers={}, subpath=None), affected_version_range=GenericVersionRange(constraints=(VersionConstraint(comparator='=', version=SemverVersion(string='8.6.0')),)), fixed_version=SemverVersion(string='8.7.0'))], references=[Reference(reference_id='', reference_type='', url='https://curl.se/docs/CVE-2024-2379.html', severities=[VulnerabilitySeverity(system=Cvssv3ScoringSystem(identifier='cvssv3.1', name='CVSSv3.1 Base Score', url='https://www.first.org/cvss/v3-1/', notes='CVSSv3.1 base score and vector'), value='Low', scoring_elements='', published_at=None, url=None)]), Reference(reference_id='', reference_type='', url='https://hackerone.com/reports/2410774', severities=[])], references_v2=[], date_published=datetime.datetime(2024, 3, 27, 8, 0, tzinfo=datetime.timezone.utc), weaknesses=[297], severities=[], url='https://curl.se/docs/CVE-2024-2379.json', original_advisory_text=None)
101101
"""
102102

103103
affected = get_item(raw_data, "affected")[0] if len(get_item(raw_data, "affected")) > 0 else []

vulnerabilities/importers/osv.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,6 @@ def parse_advisory_data_v2(
134134
references = get_references_v2(raw_data=raw_data)
135135

136136
affected_packages = []
137-
fixed_by_commits = []
138-
affected_by_commits = []
139137
for affected_pkg in raw_data.get("affected") or []:
140138
purl = get_affected_purl(affected_pkg=affected_pkg, raw_id=advisory_id)
141139

@@ -148,6 +146,8 @@ def parse_advisory_data_v2(
148146
)
149147

150148
fixed_versions = []
149+
fixed_by_commits = []
150+
affected_by_commits = []
151151
fixed_version_range = None
152152
for fixed_range in affected_pkg.get("ranges") or []:
153153
fixed_version, (introduced_commits, fixed_commits) = get_fixed_versions_and_commits(
@@ -174,6 +174,8 @@ def parse_advisory_data_v2(
174174
package=purl,
175175
affected_version_range=affected_version_range,
176176
fixed_version_range=fixed_version_range,
177+
affected_by_commits=affected_by_commits,
178+
fixed_by_commits=fixed_by_commits,
177179
)
178180
)
179181

@@ -193,8 +195,6 @@ def parse_advisory_data_v2(
193195
affected_packages=affected_packages,
194196
date_published=date_published,
195197
weaknesses=weaknesses,
196-
fixed_by_commits=fixed_by_commits,
197-
affected_by_commits=affected_by_commits,
198198
url=advisory_url,
199199
original_advisory_text=advisory_text or json.dumps(raw_data, indent=2, ensure_ascii=False),
200200
)

vulnerabilities/pipes/advisory.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,6 @@ def insert_advisory_v2(
188188
severities = get_or_create_advisory_severities(severities=advisory.severities)
189189
weaknesses = get_or_create_advisory_weaknesses(weaknesses=advisory.weaknesses)
190190
content_id = compute_content_id(advisory_data=advisory)
191-
affected_by_commits = get_or_create_advisory_code_commits(advisory.affected_by_commits)
192-
fixed_by_commits = get_or_create_advisory_code_commits(advisory.fixed_by_commits)
193191

194192
try:
195193
default_data = {
@@ -257,8 +255,12 @@ def insert_advisory_v2(
257255
impact.affecting_packages.add(*affected_packages_v2)
258256
impact.fixed_by_packages.add(*fixed_packages_v2)
259257

260-
impact.affecting_commits.add(*affected_by_commits)
261-
impact.fixed_by_commits.add(*fixed_by_commits)
258+
affected_commit_v2 = get_or_create_advisory_code_commits(
259+
affected_pkg.affected_by_commits
260+
)
261+
fixed_commit_v2 = get_or_create_advisory_code_commits(affected_pkg.fixed_by_commits)
262+
impact.affecting_commits.add(*affected_commit_v2)
263+
impact.fixed_by_commits.add(*fixed_commit_v2)
262264

263265
return advisory_obj
264266

vulnerabilities/tests/pipelines/v2_importers/test_github_osv_importer_v2.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def delete(self):
8484
assert advisory.original_advisory_text.strip().startswith("{")
8585
assert advisory.affected_packages
8686
assert advisory.affected_packages[0].package.type == "pypi"
87-
assert advisory.affected_by_commits == [
87+
assert advisory.affected_packages[0].affected_by_commits == [
8888
CodeCommitData(
8989
commit_hash="4b825dc642cb6eb9a060e54bf8d69288fbee4904",
9090
vcs_url="https://github.com/aboutcode-org/vulnerablecode",
@@ -101,7 +101,7 @@ def delete(self):
101101
),
102102
]
103103

104-
assert advisory.fixed_by_commits == [
104+
assert advisory.affected_packages[0].fixed_by_commits == [
105105
CodeCommitData(
106106
commit_hash="10081dd502dcfc0953de333fe8afb399db5f2a88",
107107
vcs_url="https://github.com/aboutcode-org/vulnerablecode",

vulnerabilities/tests/pipes/test_advisory.py

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -46,19 +46,6 @@ def setUp(self):
4646
affected_version_range=VersionRange.from_string("vers:pypi/>=1.0.0|<=2.0.0"),
4747
)
4848
],
49-
references=[Reference(url="https://example.com/with/more/info/CVE-2020-13371337")],
50-
affected_by_commits=[
51-
CodeCommitData(
52-
commit_hash="9ff29db8ec3adefefce0d37c3c9b5b2c22e59fac",
53-
vcs_url="https://github.com/aboutcode-org/vulnerablecode",
54-
)
55-
],
56-
fixed_by_commits=[
57-
CodeCommitData(
58-
commit_hash="9ff29db8ec3adefefce0d37c3c9b5b2c22e59fac",
59-
vcs_url="https://github.com/aboutcode-org/vulnerablecode",
60-
)
61-
],
6249
date_published=timezone.now(),
6350
url="https://test.com",
6451
)

vulnerabilities/tests/pipes/test_vulnerablecode_importer_pipeline_v2.py

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -53,26 +53,38 @@ def dummy_advisory():
5353
package=PackageURL.from_string("pkg:npm/foobar"),
5454
affected_version_range=VersionRange.from_string("vers:npm/<=1.2.3"),
5555
fixed_version_range=VersionRange.from_string("vers:npm/1.2.4"),
56+
fixed_by_commits=[
57+
CodeCommitData(
58+
commit_hash="9ff29db8ec3adefefce0d37c3c9b5b2c22e59fac",
59+
vcs_url="https://github.com/aboutcode-org/vulnerablecode",
60+
)
61+
],
62+
affected_by_commits=[
63+
CodeCommitData(
64+
commit_hash="ab99939678dc36b3bee0f366493df1aeef521df4",
65+
vcs_url="https://github.com/aboutcode-org/vulnerablecode",
66+
)
67+
],
5668
),
5769
AffectedPackageV2(
5870
package=PackageURL.from_string("pkg:npm/foobar"),
5971
affected_version_range=VersionRange.from_string("vers:npm/<=3.2.3"),
6072
fixed_version_range=VersionRange.from_string("vers:npm/3.2.4"),
73+
fixed_by_commits=[
74+
CodeCommitData(
75+
commit_hash="9ff29db8ec3adefefce0d37c3c9b5b2c22e59fac",
76+
vcs_url="https://github.com/aboutcode-org/vulnerablecode",
77+
)
78+
],
79+
affected_by_commits=[
80+
CodeCommitData(
81+
commit_hash="ab99939678dc36b3bee0f366493df1aeef521df4",
82+
vcs_url="https://github.com/aboutcode-org/vulnerablecode",
83+
)
84+
],
6185
),
6286
],
6387
advisory_id="ADV-123",
64-
fixed_by_commits=[
65-
CodeCommitData(
66-
commit_hash="9ff29db8ec3adefefce0d37c3c9b5b2c22e59fac",
67-
vcs_url="https://github.com/aboutcode-org/vulnerablecode",
68-
)
69-
],
70-
affected_by_commits=[
71-
CodeCommitData(
72-
commit_hash="ab99939678dc36b3bee0f366493df1aeef521df4",
73-
vcs_url="https://github.com/aboutcode-org/vulnerablecode",
74-
)
75-
],
7688
date_published=datetime.now() - timedelta(days=10),
7789
url="https://example.com/advisory/1",
7890
)

vulnerabilities/tests/test_data/archlinux/archlinux_advisoryv2-expected.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
"subpath": ""
1717
},
1818
"affected_version_range": "vers:alpm/2.3.0-1",
19-
"fixed_version_range": "vers:alpm/2.4.0-1"
19+
"fixed_version_range": "vers:alpm/2.4.0-1",
20+
"affected_by_commits": [],
21+
"fixed_by_commits": []
2022
}
2123
],
2224
"references_v2": [
@@ -29,8 +31,6 @@
2931
"severities": [],
3032
"date_published": null,
3133
"weaknesses": [],
32-
"affected_by_commits": [],
33-
"fixed_by_commits": [],
3434
"url": "https://security.archlinux.org/AVG-2781.json"
3535
},
3636
{
@@ -52,7 +52,9 @@
5252
"subpath": ""
5353
},
5454
"affected_version_range": "vers:alpm/2.36.3-1",
55-
"fixed_version_range": "vers:alpm/2.36.4-1"
55+
"fixed_version_range": "vers:alpm/2.36.4-1",
56+
"affected_by_commits": [],
57+
"fixed_by_commits": []
5658
}
5759
],
5860
"references_v2": [
@@ -65,8 +67,6 @@
6567
"severities": [],
6668
"date_published": null,
6769
"weaknesses": [],
68-
"affected_by_commits": [],
69-
"fixed_by_commits": [],
7070
"url": "https://security.archlinux.org/AVG-2780.json"
7171
},
7272
{
@@ -87,7 +87,9 @@
8787
"subpath": ""
8888
},
8989
"affected_version_range": "vers:alpm/1.0.6-5",
90-
"fixed_version_range": "vers:alpm/1.0.6-6"
90+
"fixed_version_range": "vers:alpm/1.0.6-6",
91+
"affected_by_commits": [],
92+
"fixed_by_commits": []
9193
}
9294
],
9395
"references_v2": [
@@ -105,8 +107,6 @@
105107
"severities": [],
106108
"date_published": null,
107109
"weaknesses": [],
108-
"affected_by_commits": [],
109-
"fixed_by_commits": [],
110110
"url": "https://security.archlinux.org/AVG-4.json"
111111
}
112112
]

0 commit comments

Comments
 (0)