From 02d3a1bd02be84bb0c982168e8919efa4b89e274 Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Thu, 28 Mar 2024 11:28:12 +0100 Subject: [PATCH] Respect the new ignore_vulnerabilities field It'a a list of CVE IDs or GHSA IDs which whould be ignored. In lists we still show them, but at the end and with strike through. For picking the worst for the tooltip button color we ignore them. On the security page, of all are ignored, the package is skipped. --- app/appstate.py | 21 ++++++++++++++++----- app/pkgextra.py | 3 +++ app/templates/base.html | 2 +- app/templates/outofdate.html | 4 ++-- app/templates/package.html | 2 +- app/templates/security.html | 2 +- app/web.py | 2 +- 7 files changed, 25 insertions(+), 11 deletions(-) diff --git a/app/appstate.py b/app/appstate.py index 83ab104..b208282 100644 --- a/app/appstate.py +++ b/app/appstate.py @@ -181,10 +181,11 @@ class Vulnerability: id: str url: str severity: Severity + ignored: bool = False @property - def sort_key(self) -> tuple[int, str, str]: - return (self.severity.sort_key, self.id, self.url) + def sort_key(self) -> tuple[bool, int, str, str]: + return (not self.ignored, self.severity.sort_key, self.id, self.url) class AppState: @@ -435,13 +436,23 @@ def _package(self) -> Package: @property def vulnerabilities(self) -> list[Vulnerability]: - return sorted(state.vulnerabilities.get(self.name, []), key=lambda v: v.sort_key, reverse=True) + """Returns a list of vulnerabilities for the package, sorted by severity + Also includes ignored vulnerabilities. + """ + vulnerabilities = state.vulnerabilities.get(self.name, []) + for vuln in vulnerabilities: + vuln.ignored = vuln.id in self.pkgextra.ignore_vulnerabilities + return sorted(vulnerabilities, key=lambda v: v.sort_key, reverse=True) @property def worst_vulnerability(self) -> Vulnerability | None: - if not self.vulnerabilities: + """Returns the most severe vulnerability for the package, or None if there is none. + Ignored vulnerabilities are not considered. + """ + vulnerabilities = [v for v in self.vulnerabilities if not v.ignored] + if not vulnerabilities: return None - return sorted(self.vulnerabilities, key=lambda v: v.severity.sort_key)[-1] + return sorted(vulnerabilities, key=lambda v: v.severity.sort_key)[-1] @property def can_have_vulnerabilities(self) -> bool: diff --git a/app/pkgextra.py b/app/pkgextra.py index 09ae330..db4b2cd 100644 --- a/app/pkgextra.py +++ b/app/pkgextra.py @@ -29,6 +29,9 @@ class PkgExtraEntry(BaseModel): pgp_keys_url: str | None = Field(default=None) """A website containing which keys are used to sign releases""" + ignore_vulnerabilities: list[str] = Field(default_factory=list) + """List of CVEs or GHSAs that are either not relevant or not fixable""" + class PkgExtra(BaseModel): diff --git a/app/templates/base.html b/app/templates/base.html index aa59789..22964bb 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -99,7 +99,7 @@

Base Package: {{ s.name }}

{% for vuln in s.vulnerabilities %} -
  • {{ vuln.id }} ({{ vuln.severity }})
  • +
  • {{ vuln.id }} ({{ vuln.severity }})
  • {% endfor %} {% elif not s.can_have_vulnerabilities %} diff --git a/app/templates/outofdate.html b/app/templates/outofdate.html index ee4e5aa..69a3346 100644 --- a/app/templates/outofdate.html +++ b/app/templates/outofdate.html @@ -70,7 +70,7 @@
    @@ -92,7 +92,7 @@
    {{ missing|length }} packages not found in other distros:
    diff --git a/app/templates/package.html b/app/templates/package.html index fdec984..ca35f01 100644 --- a/app/templates/package.html +++ b/app/templates/package.html @@ -84,7 +84,7 @@

    Package: {{ p.name }}<
    diff --git a/app/templates/security.html b/app/templates/security.html index 8405d80..be28398 100644 --- a/app/templates/security.html +++ b/app/templates/security.html @@ -40,7 +40,7 @@

    {{ vulnerable|length }} packages with diff --git a/app/web.py b/app/web.py index 6d74d4b..30413c3 100644 --- a/app/web.py +++ b/app/web.py @@ -253,7 +253,7 @@ async def security(request: Request, response: Response) -> Response: return templates.TemplateResponse("security.html", { "request": request, - "vulnerable": [s for s in state.sources.values() if s.vulnerabilities], + "vulnerable": [s for s in state.sources.values() if s.worst_vulnerability is not None], "sources": state.sources.values(), "known": [s for s in state.sources.values() if s.can_have_vulnerabilities], "unknown": [s for s in state.sources.values() if not s.can_have_vulnerabilities],