Skip to content

Commit 80da375

Browse files
authored
Merge pull request #1103 from TG1999/add_istio_improver
Add istio improver
2 parents 87fb34a + 8b99c6d commit 80da375

File tree

4 files changed

+420
-0
lines changed

4 files changed

+420
-0
lines changed

vulnerabilities/importers/istio.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,20 @@
66
# See https://github.com/nexB/vulnerablecode for support or download.
77
# See https://aboutcode.org for more information about nexB OSS projects.
88
#
9+
import logging
910
import re
11+
from datetime import datetime
1012
from pathlib import Path
13+
from typing import Iterable
14+
from typing import List
15+
from typing import Mapping
16+
from typing import Optional
1117
from typing import Set
1218

1319
import pytz
1420
import saneyaml
1521
from dateutil import parser
22+
from django.db.models.query import QuerySet
1623
from packageurl import PackageURL
1724
from univers.version_constraint import VersionConstraint
1825
from univers.version_range import GitHubVersionRange
@@ -23,10 +30,22 @@
2330
from vulnerabilities.importer import AffectedPackage
2431
from vulnerabilities.importer import Importer
2532
from vulnerabilities.importer import Reference
33+
from vulnerabilities.importer import UnMergeablePackageError
34+
from vulnerabilities.improver import Improver
35+
from vulnerabilities.improver import Inference
36+
from vulnerabilities.models import Advisory
37+
from vulnerabilities.package_managers import GitHubTagsAPI
38+
from vulnerabilities.package_managers import VersionAPI
39+
from vulnerabilities.utils import AffectedPackage as LegacyAffectedPackage
40+
from vulnerabilities.utils import get_affected_packages_by_patched_package
41+
from vulnerabilities.utils import nearest_patched_package
42+
from vulnerabilities.utils import resolve_version_range
2643
from vulnerabilities.utils import split_markdown_front_matter
2744

2845
is_release = re.compile(r"^[\d.]+$", re.IGNORECASE).match
2946

47+
logger = logging.getLogger(__name__)
48+
3049

3150
class IstioImporter(Importer):
3251
spdx_license_expression = "Apache-2.0"
@@ -136,3 +155,70 @@ def get_data_from_md(self, path):
136155
with open(path) as f:
137156
front_matter, _ = split_markdown_front_matter(f.read())
138157
return saneyaml.load(front_matter)
158+
159+
160+
class IstioImprover(Improver):
161+
def __init__(self) -> None:
162+
self.versions_fetcher_by_purl: Mapping[str, VersionAPI] = {}
163+
self.vesions_by_purl = {}
164+
165+
@property
166+
def interesting_advisories(self) -> QuerySet:
167+
return Advisory.objects.filter(created_by=IstioImporter.qualified_name)
168+
169+
def get_package_versions(
170+
self, package_url: PackageURL, until: Optional[datetime] = None
171+
) -> List[str]:
172+
"""
173+
Return a list of `valid_versions` for the `package_url`
174+
"""
175+
api_name = "istio/istio"
176+
versions_fetcher = GitHubTagsAPI()
177+
return versions_fetcher.get_until(package_name=api_name, until=until).valid_versions
178+
179+
def get_inferences(self, advisory_data: AdvisoryData) -> Iterable[Inference]:
180+
"""
181+
Yield Inferences for the given advisory data
182+
"""
183+
if not advisory_data.affected_packages:
184+
return
185+
for affected_package in advisory_data.affected_packages:
186+
purl = affected_package.package
187+
affected_version_range = affected_package.affected_version_range
188+
pkg_type = purl.type
189+
pkg_namespace = purl.namespace
190+
pkg_name = purl.name
191+
if not self.vesions_by_purl.get("istio/istio"):
192+
valid_versions = self.get_package_versions(
193+
package_url=purl, until=advisory_data.date_published
194+
)
195+
self.vesions_by_purl["istio/istio"] = valid_versions
196+
valid_versions = self.vesions_by_purl["istio/istio"]
197+
aff_vers, unaff_vers = resolve_version_range(
198+
affected_version_range=affected_version_range,
199+
package_versions=valid_versions,
200+
)
201+
affected_purls = [
202+
PackageURL(type=pkg_type, namespace=pkg_namespace, name=pkg_name, version=version)
203+
for version in aff_vers
204+
]
205+
206+
unaffected_purls = [
207+
PackageURL(type=pkg_type, namespace=pkg_namespace, name=pkg_name, version=version)
208+
for version in unaff_vers
209+
]
210+
211+
affected_packages: List[LegacyAffectedPackage] = nearest_patched_package(
212+
vulnerable_packages=affected_purls, resolved_packages=unaffected_purls
213+
)
214+
215+
for (
216+
fixed_package,
217+
affected_packages,
218+
) in get_affected_packages_by_patched_package(affected_packages).items():
219+
yield Inference.from_advisory_data(
220+
advisory_data,
221+
confidence=100, # We are getting all valid versions to get this inference
222+
affected_purls=affected_packages,
223+
fixed_purl=fixed_package,
224+
)

vulnerabilities/improvers/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
importers.github.GitHubBasicImprover,
1818
importers.debian.DebianBasicImprover,
1919
importers.gitlab.GitLabBasicImprover,
20+
importers.istio.IstioImprover,
2021
oval.DebianOvalBasicImprover,
2122
oval.UbuntuOvalBasicImprover,
2223
]

0 commit comments

Comments
 (0)