Skip to content

Commit 79a7e7f

Browse files
committed
Update V2 pipelines to create AffectedPackageV2
Signed-off-by: Keshav Priyadarshi <git@keshav.space>
1 parent a8846f8 commit 79a7e7f

15 files changed

+114
-153
lines changed

vulnerabilities/importer.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ def __post_init__(self):
360360
)
361361

362362
def __lt__(self, other):
363-
if not isinstance(other, AffectedPackage):
363+
if not isinstance(other, AffectedPackageV2):
364364
return NotImplemented
365365
return self._cmp_key() < other._cmp_key()
366366

@@ -446,8 +446,6 @@ class AdvisoryData:
446446
original_advisory_text: Optional[str] = None
447447

448448
def __post_init__(self):
449-
if self.date_published and not self.date_published.tzinfo:
450-
logger.warning(f"AdvisoryData with no tzinfo: {self!r}")
451449
if self.summary:
452450
self.summary = self.clean_summary(self.summary)
453451

vulnerabilities/importers/osv.py

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
from vulnerabilities.importer import AdvisoryData
2525
from vulnerabilities.importer import AffectedPackage
26+
from vulnerabilities.importer import AffectedPackageV2
2627
from vulnerabilities.importer import Reference
2728
from vulnerabilities.importer import ReferenceV2
2829
from vulnerabilities.importer import VulnerabilitySeverity
@@ -144,19 +145,27 @@ def parse_advisory_data_v2(
144145
supported_ecosystem=purl.type,
145146
)
146147

148+
fixed_versions = []
149+
fixed_version_range = None
147150
for fixed_range in affected_pkg.get("ranges") or []:
148151
fixed_version = get_fixed_versions(
149152
fixed_range=fixed_range, raw_id=advisory_id, supported_ecosystem=purl.type
150153
)
154+
fixed_versions.extend([v.string for v in fixed_version])
151155

152-
for version in fixed_version:
153-
affected_packages.append(
154-
AffectedPackage(
155-
package=purl,
156-
affected_version_range=affected_version_range,
157-
fixed_version=version,
158-
)
156+
fixed_version_range = (
157+
get_fixed_version_range(fixed_versions, purl.type) if fixed_versions else None
158+
)
159+
160+
if fixed_version_range or affected_version_range:
161+
affected_packages.append(
162+
AffectedPackageV2(
163+
package=purl,
164+
affected_version_range=affected_version_range,
165+
fixed_version_range=fixed_version_range,
159166
)
167+
)
168+
160169
database_specific = raw_data.get("database_specific") or {}
161170
cwe_ids = database_specific.get("cwe_ids") or []
162171
weaknesses = list(map(get_cwe_id, cwe_ids))
@@ -334,6 +343,13 @@ def get_affected_version_range(affected_pkg, raw_id, supported_ecosystem):
334343
)
335344

336345

346+
def get_fixed_version_range(versions, ecosystem):
347+
try:
348+
return RANGE_CLASS_BY_SCHEMES[ecosystem].from_versions(versions)
349+
except Exception as e:
350+
logger.error(f"Failed to create VersionRange from: {versions}: error:{e!r}")
351+
352+
337353
def get_fixed_versions(fixed_range, raw_id, supported_ecosystem) -> List[Version]:
338354
"""
339355
Return a list of unique fixed univers Versions given a ``fixed_range``

vulnerabilities/pipelines/v2_importers/apache_httpd_importer.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
from univers.versions import SemverVersion
2323

2424
from vulnerabilities.importer import AdvisoryData
25-
from vulnerabilities.importer import AffectedPackage
25+
from vulnerabilities.importer import AffectedPackageV2
2626
from vulnerabilities.importer import ReferenceV2
2727
from vulnerabilities.importer import VulnerabilitySeverity
2828
from vulnerabilities.pipelines import VulnerableCodeBaseImporterPipelineV2
@@ -151,7 +151,6 @@ class ApacheHTTPDImporterPipeline(VulnerableCodeBaseImporterPipelineV2):
151151
spdx_license_expression = "Apache-2.0"
152152
license_url = "https://www.apache.org/licenses/LICENSE-2.0"
153153
base_url = "https://httpd.apache.org/security/json/"
154-
unfurl_version_ranges = True
155154

156155
links = []
157156

@@ -219,7 +218,6 @@ class ApacheHTTPDImporterPipeline(VulnerableCodeBaseImporterPipelineV2):
219218
"pre_ajp_proxy",
220219
]
221220
)
222-
unfurl_version_ranges = True
223221

224222
@classmethod
225223
def steps(cls):
@@ -292,7 +290,7 @@ def to_advisory(self, data):
292290
affected_version_range = self.to_version_ranges(versions_data, fixed_versions)
293291
if affected_version_range:
294292
affected_packages.append(
295-
AffectedPackage(
293+
AffectedPackageV2(
296294
package=PackageURL(
297295
type="apache",
298296
name="httpd",

vulnerabilities/pipelines/v2_importers/curl_importer.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,9 @@
1212
from cwe2.database import Database
1313
from packageurl import PackageURL
1414
from univers.version_range import GenericVersionRange
15-
from univers.versions import SemverVersion
1615

1716
from vulnerabilities.importer import AdvisoryData
18-
from vulnerabilities.importer import AffectedPackage
17+
from vulnerabilities.importer import AffectedPackageV2
1918
from vulnerabilities.importer import ReferenceV2
2019
from vulnerabilities.importer import VulnerabilitySeverity
2120
from vulnerabilities.pipelines import VulnerableCodeBaseImporterPipelineV2
@@ -37,7 +36,6 @@ class CurlImporterPipeline(VulnerableCodeBaseImporterPipelineV2):
3736
license_url = "https://curl.se/docs/copyright.html"
3837
repo_url = "https://github.com/curl/curl-www/"
3938
url = "https://curl.se/docs/vuln.json"
40-
unfurl_version_ranges = True
4139

4240
@classmethod
4341
def steps(cls):
@@ -77,16 +75,16 @@ def parse_curl_advisory(raw_data) -> AdvisoryData:
7775
version_type = get_item(ranges, "type") if get_item(ranges, "type") else ""
7876
fixed_version = events.get("fixed")
7977
if version_type == "SEMVER" and fixed_version:
80-
fixed_version = SemverVersion(fixed_version)
78+
fixed_version_range = GenericVersionRange.from_versions([fixed_version])
8179

8280
purl = PackageURL(type="generic", namespace="curl.se", name="curl")
8381
versions = affected.get("versions") or []
8482
affected_version_range = GenericVersionRange.from_versions(versions)
8583

86-
affected_package = AffectedPackage(
84+
affected_package = AffectedPackageV2(
8785
package=purl,
8886
affected_version_range=affected_version_range,
89-
fixed_version=fixed_version,
87+
fixed_version_range=fixed_version_range,
9088
)
9189

9290
database_specific = raw_data.get("database_specific") or {}

vulnerabilities/pipelines/v2_importers/elixir_security_importer.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from univers.version_range import HexVersionRange
1818

1919
from vulnerabilities.importer import AdvisoryData
20-
from vulnerabilities.importer import AffectedPackage
20+
from vulnerabilities.importer import AffectedPackageV2
2121
from vulnerabilities.importer import ReferenceV2
2222
from vulnerabilities.pipelines import VulnerableCodeBaseImporterPipelineV2
2323
from vulnerabilities.utils import is_cve
@@ -26,7 +26,7 @@
2626

2727
class ElixirSecurityImporterPipeline(VulnerableCodeBaseImporterPipelineV2):
2828
"""
29-
Elixir Security Advisiories Importer Pipeline
29+
Elixir Security Advisories Importer Pipeline
3030
3131
This pipeline imports security advisories for elixir.
3232
"""
@@ -35,7 +35,6 @@ class ElixirSecurityImporterPipeline(VulnerableCodeBaseImporterPipelineV2):
3535
spdx_license_expression = "CC0-1.0"
3636
license_url = "https://github.com/dependabot/elixir-security-advisories/blob/master/LICENSE.txt"
3737
repo_url = "git+https://github.com/dependabot/elixir-security-advisories"
38-
unfurl_version_ranges = True
3938

4039
@classmethod
4140
def steps(cls):
@@ -118,7 +117,7 @@ def process_file(self, file, base_path) -> Iterable[AdvisoryData]:
118117
affected_packages = []
119118
if pkg_name:
120119
affected_packages.append(
121-
AffectedPackage(
120+
AffectedPackageV2(
122121
package=PackageURL(type="hex", name=pkg_name),
123122
affected_version_range=HexVersionRange(constraints=constraints),
124123
)

vulnerabilities/pipelines/v2_importers/github_osv_importer.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ class GithubOSVImporterPipeline(VulnerableCodeBaseImporterPipelineV2):
2929
spdx_license_expression = "CC-BY-4.0"
3030
license_url = "https://github.com/github/advisory-database/blob/main/LICENSE.md"
3131
repo_url = "git+https://github.com/github/advisory-database/"
32-
unfurl_version_ranges = True
3332

3433
@classmethod
3534
def steps(cls):

vulnerabilities/pipelines/v2_importers/gitlab_importer.py

Lines changed: 17 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
import traceback
1313
from pathlib import Path
1414
from typing import Iterable
15-
from typing import List
1615
from typing import Tuple
1716

1817
import pytz
@@ -21,12 +20,10 @@
2120
from fetchcode.vcs import fetch_via_vcs
2221
from packageurl import PackageURL
2322
from univers.version_range import RANGE_CLASS_BY_SCHEMES
24-
from univers.version_range import VersionRange
2523
from univers.version_range import from_gitlab_native
26-
from univers.versions import Version
2724

2825
from vulnerabilities.importer import AdvisoryData
29-
from vulnerabilities.importer import AffectedPackage
26+
from vulnerabilities.importer import AffectedPackageV2
3027
from vulnerabilities.importer import ReferenceV2
3128
from vulnerabilities.pipelines import VulnerableCodeBaseImporterPipelineV2
3229
from vulnerabilities.utils import build_description
@@ -45,7 +42,6 @@ class GitLabImporterPipeline(VulnerableCodeBaseImporterPipelineV2):
4542
spdx_license_expression = "MIT"
4643
license_url = "https://gitlab.com/gitlab-org/advisories-community/-/blob/main/LICENSE"
4744
repo_url = "git+https://gitlab.com/gitlab-org/advisories-community/"
48-
unfurl_version_ranges = True
4945

5046
@classmethod
5147
def steps(cls):
@@ -177,27 +173,6 @@ def get_purl(package_slug, purl_type_by_gitlab_scheme, logger):
177173
return
178174

179175

180-
def extract_affected_packages(
181-
affected_version_range: VersionRange,
182-
fixed_versions: List[Version],
183-
purl: PackageURL,
184-
) -> Iterable[AffectedPackage]:
185-
"""
186-
Yield AffectedPackage objects, one for each fixed_version
187-
188-
In case of gitlab advisory data we get a list of fixed_versions and a affected_version_range.
189-
Since we can not determine which package fixes which range.
190-
We store the all the fixed_versions with the same affected_version_range in the advisory.
191-
Later the advisory data is used to be inferred in the GitLabBasicImprover.
192-
"""
193-
for fixed_version in fixed_versions:
194-
yield AffectedPackage(
195-
package=purl,
196-
fixed_version=fixed_version,
197-
affected_version_range=affected_version_range,
198-
)
199-
200-
201176
def parse_gitlab_advisory(
202177
file, base_path, gitlab_scheme_by_purl_type, purl_type_by_gitlab_scheme, logger
203178
):
@@ -276,7 +251,7 @@ def parse_gitlab_advisory(
276251
fixed_versions = gitlab_advisory.get("fixed_versions") or []
277252
affected_range = gitlab_advisory.get("affected_range")
278253
gitlab_native_schemes = set(["pypi", "gem", "npm", "go", "packagist", "conan"])
279-
vrc: VersionRange = RANGE_CLASS_BY_SCHEMES[purl.type]
254+
vrc = RANGE_CLASS_BY_SCHEMES[purl.type]
280255
gitlab_scheme = gitlab_scheme_by_purl_type[purl.type]
281256
try:
282257
if affected_range:
@@ -296,38 +271,33 @@ def parse_gitlab_advisory(
296271
for fixed_version in fixed_versions:
297272
try:
298273
fixed_version = vrc.version_class(fixed_version)
299-
parsed_fixed_versions.append(fixed_version)
274+
parsed_fixed_versions.append(fixed_version.string)
300275
except Exception as e:
301276
logger(
302277
f"parse_yaml_file: fixed_version is not parsable`: {fixed_version!r} error: {e!r}\n {traceback.format_exc()}",
303278
level=logging.ERROR,
304279
)
305280

306-
if parsed_fixed_versions:
307-
affected_packages = list(
308-
extract_affected_packages(
309-
affected_version_range=affected_version_range,
310-
fixed_versions=parsed_fixed_versions,
311-
purl=purl,
312-
)
313-
)
314-
else:
315-
if not affected_version_range:
316-
affected_packages = []
317-
else:
318-
affected_packages = [
319-
AffectedPackage(
320-
package=purl,
321-
affected_version_range=affected_version_range,
322-
)
323-
]
281+
if affected_version_range:
282+
vrc = affected_version_range.__class__
283+
284+
fixed_version_range = vrc.from_versions(parsed_fixed_versions)
285+
if not fixed_version_range and not affected_version_range:
286+
return
287+
288+
affected_package = AffectedPackageV2(
289+
package=purl,
290+
affected_version_range=affected_version_range,
291+
fixed_version_range=fixed_version_range,
292+
)
293+
324294
return AdvisoryData(
325295
advisory_id=advisory_id,
326296
aliases=aliases,
327297
summary=summary,
328298
references_v2=references,
329299
date_published=date_published,
330-
affected_packages=affected_packages,
300+
affected_packages=[affected_package],
331301
weaknesses=cwe_list,
332302
url=advisory_url,
333303
original_advisory_text=json.dumps(gitlab_advisory, indent=2, ensure_ascii=False),

0 commit comments

Comments
 (0)