Skip to content

Commit 7778009

Browse files
committed
Removed fixed version resolver for safetydb
Signed-off-by: Omkar Phansopkar <omkarphansopkar@gmail.com>
1 parent 9352e62 commit 7778009

4 files changed

Lines changed: 10 additions & 138 deletions

File tree

vulntotal/datasources/safetydb.py

Lines changed: 4 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,7 @@
1212
from typing import List
1313

1414
import requests
15-
from fetchcode.package_versions import versions
1615
from packageurl import PackageURL
17-
from univers.version_range import PypiVersionRange
18-
from univers.versions import PypiVersion
1916

2017
from vulntotal.validator import DataSource
2118
from vulntotal.validator import InvalidCVEError
@@ -53,8 +50,7 @@ def datasource_advisory(self, purl) -> Iterable[VendorData]:
5350
return []
5451
advisory = self.fetch_advisory()
5552
self._raw_dump.append(advisory)
56-
self._versions = sorted([PypiVersion(ver.value) for ver in versions(str(purl))])
57-
return parse_advisory(advisory, purl, self._versions)
53+
return parse_advisory(advisory, purl)
5854

5955
def datasource_advisory_from_cve(self, cve: str) -> Iterable[VendorData]:
6056
if not cve.upper().startswith("CVE-"):
@@ -65,13 +61,10 @@ def datasource_advisory_from_cve(self, cve: str) -> Iterable[VendorData]:
6561

6662
@classmethod
6763
def supported_ecosystem(cls):
68-
# source - @TODO
6964
return {"pypi": "PyPI"}
7065

7166

72-
def parse_advisory(
73-
response, purl: PackageURL, all_versions: List[PypiVersion]
74-
) -> Iterable[VendorData]:
67+
def parse_advisory(response, purl: PackageURL) -> Iterable[VendorData]:
7568
"""
7669
Parse response from safetydb API and yield VendorData
7770
@@ -83,14 +76,11 @@ def parse_advisory(
8376
"""
8477

8578
for advisory in response.get(purl.name):
86-
vulnerable_version_range_string = "vers:pypi/" + advisory.get("v").replace(",", "|")
87-
vulnerable_version_range = PypiVersionRange.from_string(vulnerable_version_range_string)
88-
8979
yield VendorData(
9080
purl=PackageURL(purl.type, purl.namespace, purl.name),
9181
aliases=[advisory.get("cve"), advisory.get("id")],
9282
affected_versions=sorted(advisory.get("specs")),
93-
fixed_versions=get_patched_versions(all_versions, vulnerable_version_range),
83+
fixed_versions=[],
9484
)
9585

9686

@@ -109,81 +99,11 @@ def parse_advisory_for_cve(response, cve: str) -> Iterable[VendorData]:
10999
if package == "$meta":
110100
continue
111101

112-
all_versions = sorted(
113-
[PypiVersion(ver.value) for ver in versions(str(PackageURL(type="pypi", name=package)))]
114-
)
115-
116102
for advisory in advisories:
117103
if advisory.get("cve") == cve:
118-
vulnerable_version_range_string = "vers:pypi/" + advisory.get("v").replace(",", "|")
119-
vulnerable_version_range = PypiVersionRange.from_string(
120-
vulnerable_version_range_string
121-
)
122-
123104
yield VendorData(
124105
purl=PackageURL(type="pypi", name=package),
125106
aliases=[advisory.get("cve"), advisory.get("id")],
126107
affected_versions=sorted(advisory.get("specs")),
127-
fixed_versions=get_patched_versions(all_versions, vulnerable_version_range),
108+
fixed_versions=[],
128109
)
129-
130-
131-
def get_patched_versions(
132-
all_versions: List[PypiVersion],
133-
vulnerable_version_range: PypiVersionRange,
134-
):
135-
"""
136-
Get the first patched version from the list of all versions of a package
137-
138-
Parameters:
139-
all_versions: A list containing PackageVersion of a package
140-
vulnerable_version_range: A PypiVersionRange object specifying the vulnerable version range
141-
142-
Returns:
143-
A PackageVersion object containing the first patched version of the package
144-
"""
145-
146-
# last_patched = None
147-
# for version in reversed(all_versions):
148-
# if version in vulnerable_version_range:
149-
# if last_patched is not None:
150-
# return [str(last_patched.value)]
151-
# return []
152-
# last_patched = version
153-
# return []
154-
155-
patched_version_ranges: List[str] = []
156-
current_patched_range_start: PypiVersion = None
157-
current_patched_range_latest: PypiVersion = None
158-
159-
def resolve_patched_range():
160-
if current_patched_range_start is not None:
161-
if current_patched_range_latest == current_patched_range_start:
162-
patched_version_ranges.append(str(current_patched_range_start.value))
163-
else:
164-
patched_version_ranges.append(
165-
f">={current_patched_range_start.value},<={current_patched_range_latest.value}"
166-
)
167-
168-
for version in all_versions:
169-
if version in vulnerable_version_range:
170-
resolve_patched_range()
171-
current_patched_range_start = None
172-
current_patched_range_latest = None
173-
else:
174-
if current_patched_range_start is None:
175-
current_patched_range_start = version
176-
current_patched_range_latest = version
177-
resolve_patched_range()
178-
179-
# Remove upper bound from the last fixed range
180-
if len(patched_version_ranges) > 0:
181-
patched_version_ranges[-1] = patched_version_ranges[-1].split(",")[0]
182-
183-
# Ensure that >= is only present if there are fragmented fixed ranges
184-
# eg. For vulnerable spec "<2.2.5 >=2.3.0 <2.3.2",,fixed range => "2.2.5, >=2.3.2"
185-
# eg. For vulnerable spec "<2.2.5", fixed range => "2.2.5
186-
if len(patched_version_ranges) == 1:
187-
patched_version_ranges[-1] = patched_version_ranges[-1][2:]
188-
189-
return patched_version_ranges

vulntotal/tests/test_data/safetydb/parse_advisory-expected.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,25 @@
22
{
33
"purl": "pkg:pypi/flask",
44
"affected_versions": ["<0.12.3"],
5-
"fixed_versions": ["0.12.3"],
5+
"fixed_versions": [],
66
"aliases": ["CVE-2018-1000656", "pyup.io-36388"]
77
},
88
{
99
"purl": "pkg:pypi/flask",
1010
"affected_versions": ["<0.12.3"],
11-
"fixed_versions": ["0.12.3"],
11+
"fixed_versions": [],
1212
"aliases": ["CVE-2019-1010083", "pyup.io-38654"]
1313
},
1414
{
1515
"purl": "pkg:pypi/flask",
1616
"affected_versions": ["<0.6.1"],
17-
"fixed_versions": ["0.6.1"],
17+
"fixed_versions": [],
1818
"aliases": ["PVE-2021-25820", "pyup.io-25820"]
1919
},
2020
{
2121
"purl": "pkg:pypi/flask",
2222
"affected_versions": ["<2.2.5", ">=2.3.0,<2.3.2"],
23-
"fixed_versions": ["2.2.5", ">=2.3.2"],
23+
"fixed_versions": [],
2424
"aliases": ["CVE-2023-30861", "pyup.io-55261"]
2525
}
2626
]

vulntotal/tests/test_data/safetydb/parse_advisory_cve-expected.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
{
33
"purl": "pkg:pypi/flask",
44
"affected_versions": ["<0.12.3"],
5-
"fixed_versions": ["0.12.3"],
5+
"fixed_versions": [],
66
"aliases": ["CVE-2019-1010083", "pyup.io-38654"]
77
}
88
]

vulntotal/tests/test_safetydb.py

Lines changed: 1 addition & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,7 @@
1111
from pathlib import Path
1212

1313
from commoncode import testcase
14-
from fetchcode.package_versions import versions
1514
from packageurl import PackageURL
16-
from univers.version_range import PypiVersionRange
17-
from univers.versions import PypiVersion
1815

1916
from vulnerabilities.tests import util_tests
2017
from vulntotal.datasources import safetydb
@@ -28,9 +25,8 @@ def test_parse_advisory(self):
2825
advisory_file = self.get_test_loc("advisory.json")
2926
with open(advisory_file) as f:
3027
advisory = json.load(f)
31-
all_versions = sorted([PypiVersion(ver.value) for ver in versions(str(purl))])
3228

33-
results = [adv.to_dict() for adv in safetydb.parse_advisory(advisory, purl, all_versions)]
29+
results = [adv.to_dict() for adv in safetydb.parse_advisory(advisory, purl)]
3430
expected_file = self.get_test_loc("parse_advisory-expected.json", must_exist=False)
3531
util_tests.check_results_against_json(results, expected_file)
3632

@@ -43,47 +39,3 @@ def test_parse_advisory_for_cve(self):
4339
results = [adv.to_dict() for adv in safetydb.parse_advisory_for_cve(advisory, cve)]
4440
expected_file = self.get_test_loc("parse_advisory_cve-expected.json", must_exist=False)
4541
util_tests.check_results_against_json(results, expected_file)
46-
47-
def test_get_patched_versions(self):
48-
# Ref - flask package
49-
all_versions = [
50-
PypiVersion(ver)
51-
for ver in [
52-
"0.12.2",
53-
"0.12.3",
54-
"0.12.4",
55-
"0.12.5",
56-
"1.0",
57-
"2.2.4",
58-
"2.2.5",
59-
"2.3.0",
60-
"2.3.1",
61-
"2.3.2",
62-
"2.3.3",
63-
"3.0.0",
64-
"3.0.1",
65-
"3.0.2",
66-
"3.0.3",
67-
]
68-
]
69-
70-
test_cases = [
71-
{
72-
"vulnerable_version_range": PypiVersionRange.from_string("vers:pypi/<0.12.3"),
73-
"expected_patched_version_ranges": ["0.12.3"],
74-
},
75-
{
76-
"vulnerable_version_range": PypiVersionRange.from_string(
77-
"vers:pypi/<2.2.5|>=2.3.0|<2.3.2"
78-
),
79-
"expected_patched_version_ranges": ["2.2.5", ">=2.3.2"],
80-
},
81-
]
82-
83-
for test_case in test_cases:
84-
results = safetydb.get_patched_versions(
85-
all_versions, test_case["vulnerable_version_range"]
86-
)
87-
util_tests.check_results_against_expected(
88-
results, test_case["expected_patched_version_ranges"]
89-
)

0 commit comments

Comments
 (0)