8000 Add explicit version information to emitted records by wagoodman · Pull Request #763 · anchore/vunnel · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Add explicit version information to emitted records #763

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open
  •  
  •  
  •  
1 change: 0 additions & 1 deletion .github/actions/quality-gate/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ runs:
working-directory: tests/quality
run: poetry run make capture provider=${{ inputs.provider }}


- name: Validate provider results
shell: bash
working-directory: tests/quality
Expand Down
216 changes: 216 additions & 0 deletions schema/vulnerability/os/schema-1.0.3.json
Copy link
Contributor Author
@wagoodman wagoodman Jan 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

diff schema/vulnerability/os/schema-1.0.2.json schema/vulnerability/os/schema-1.0.3.json
72a73,89
>                 "OS": {
>                   "type": "object",
>                   "properties": {
>                     "ID": {
>                       "type": "string"
>                     },
>                     "Version": {
>                       "type": "string"
>                     }
>                   }
>                 },
>                 "Architectures": {
>                   "type": "array",
>                   "items": {
>                     "type": "string"
>                   }
>                 },

EDBE
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"title": "os-vulnerability",
"description": "represents vulnerability records for common linux distributions",
"properties": {
"Vulnerability": {
"type": "object",
"properties": {
"CVSS": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"base_metrics": {
"type": "object",
"properties": {
"base_score": {
"type": "number"
},
"base_severity": {
"type": "string"
},
"exploitability_score": {
"type": "number"
},
"impact_score": {
"type": "number"
}
},
"required": [
"base_score",
"base_severity",
"exploitability_score",
"impact_score"
]
},
"status": {
"type": "string"
},
"vector_string": {
"type": "string"
},
"version": {
"type": "string"
}
},
"required": [
"base_metrics",
"status",
"vector_string",
"version"
]
}
]
},
"Description": {
"type": "string"
},
"FixedIn": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"Name": {
"type": "string"
},
"NamespaceName": {
"type": "string"
},
"OS": {
"type": "object",
"properties": {
"ID": {
"type": "string"
},
"Version": {
"type": "string"
}
}
},
"Architectures": {
"type": "array",
"items": {
"type": "string"
}
},
"VendorAdvisory": {
"type": "object",
"properties": {
"AdvisorySummary": {
"type": "array",
"items": {}
},
"NoAdvisory": {
"type": "boolean"
}
},
"required": [
"NoAdvisory"
]
},
"Version": {
"type": "string"
},
"VersionFormat": {
"type": "string"
},
"VulnerableRange": {
"type": ["string", "null"]
},
"Module": {
"type": ["string", "null"]
},
"Issued": {
"type": "string",
"description": "date the fix was made available"
}
},
"required": [
"Name",
"NamespaceName",
"Version",
"VersionFormat"
]
}
]
},
"Link": {
"type": "string"
},
"Metadata": {
"type": "object",
"properties": {
"Issued": {
"type": "string",
"description": "date the vulnerability was published"
},
"Updated": {
"type": "string",
"description": "date the vulnerability was last updated"
},
"Withdrawn": {
"type": "string",
"description": "date the vulnerability was withdrawn"
},
"RefId": {
"type": "string"
},
"CVE": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"Name": {
"type": "string"
},
"Link": {
"type": "string"
}
},
"required": [
"Name"
]
}
]
},
"NVD": {
"type": "object",
"properties": {
"CVSSv2": {
"type": "object",
"properties": {
"Score": {
"type": "number"
},
"Vectors": {
"type": "string"
}
},
"required": [
"Score"
]
}
}
}
}
},
"Name": {
"type": "string"
},
"NamespaceName": {
"type": "string"
},
"Severity": {
"type": "string"
}
},
"required": [
"Description",
"FixedIn",
"Link",
"Metadata",
"Name",
"NamespaceName",
"Severity"
]
}
},
"required": [
"Vulnerability"
]
}
6 changes: 6 additions & 0 deletions src/vunnel/providers/alpine/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

from vunnel import workspace

# namespace should match the value found in the /etc/os-release ID field
namespace = "alpine"
feedtype = "vulnerabilities"
purge_unreported = True
Expand Down Expand Up @@ -242,11 +243,16 @@ def _normalize(self, release, dbtype_data_dict): # noqa: C901, PLR0912
fixed_el["NamespaceName"] = namespace + ":" + str(release)
fixed_el["Name"] = pkg
fixed_el["Version"] = pkg_version
fixed_el["OS"] = self.os_info(release)

vuln_record["Vulnerability"]["FixedIn"].append(fixed_el)

return vuln_dict

def os_info(self, release: any) -> dict[str, str]:
# note: ID is based off of the /etc/os-release ID field
return {"ID": namespace, "Version": str(release)}

def get(self):
"""
Download, load and normalize alpine sec db and return a dict of releae - list of vulnerability records
Expand Down
9 changes: 9 additions & 0 deletions src/vunnel/providers/amazon/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from vunnel.utils import http, rpm

# namespace should match the value found in the /etc/os-release ID field
namespace = "amzn"

AlasSummary = namedtuple("AlasSummary", ["id", "url", "sev", "cves"])
Expand Down Expand Up @@ -235,6 +236,13 @@ def __init__(self):
self.NamespaceName = None
self.VersionFormat = None
self.Version = None
self.OS = None


class OperatingSystem(JsonifierMixin):
def __init__(self, identifier: str | None = None, version: str | None = None):
self.ID = identifier
self.Version = version


class PackagesHTMLParser(HTMLParser):
Expand Down Expand Up @@ -316,6 +324,7 @@ def map_to_vulnerability(version, alas, fixed_in, description):
f.NamespaceName = v.NamespaceName
f.VersionFormat = "rpm"
f.Version = item.ver
f.OS = OperatingSystem(identifier=namespace, version=version)
v.FixedIn.append(f)

return v
11 changes: 9 additions & 2 deletions src/vunnel/providers/debian/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
"sid": "unstable",
}

# namespace should match the value found in the /etc/os-release ID field
namespace = "debian"


class Parser:
_json_url_ = "https://security-tracker.debian.org/tracker/data/json"
Expand Down Expand Up @@ -316,7 +319,7 @@ def _normalize_json(self, ns_cve_dsalist=None): # noqa: PLR0912,PLR0915,C901
# populate the static information about the new vuln record
vuln_record["Vulnerability"]["Description"] = vulnerability_data.get("description", "")
vuln_record["Vulnerability"]["Name"] = str(vid)
vuln_record["Vulnerability"]["NamespaceName"] = "debian:" + str(relno)
vuln_record["Vulnerability"]["NamespaceName"] = namespace + ":" + str(relno)
vuln_record["Vulnerability"]["Link"] = "https://security-tracker.debian.org/tracker/" + str(vid)
vuln_record["Vulnerability"]["Severity"] = "Unknown"
else:
Expand Down Expand Up @@ -357,8 +360,12 @@ def _normalize_json(self, ns_cve_dsalist=None): # noqa: PLR0912,PLR0915,C901
skip_fixedin = False
fixed_el = {
"Name": pkg,
"NamespaceName": "debian:" + str(relno),
"NamespaceName": namespace + ":" + str(relno),
"VersionFormat": "dpkg",
"OS": {
"ID": namespace,
"Version": str(relno),
},
}

if "fixed_version" in distro_record:
Expand Down
22 changes: 21 additions & 1 deletion src/vunnel/providers/mariner/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from vunnel.providers.mariner.model import Definition, RpminfoObject, RpminfoState, RpminfoTest
from vunnel.utils import http
from vunnel.utils.vulnerability import FixedIn, Vulnerability
from vunnel.utils.vulnerability import FixedIn, OperatingSystem, Vulnerability

if TYPE_CHECKING:
import logging
Expand Down Expand Up @@ -166,6 +166,10 @@ def make_fixed_in(self, definition: Definition) -> FixedIn | None:
VulnerableRange=vulnerability_range_str,
Module=None,
VendorAdvisory=None,
OS=OperatingSystem(
ID=VERSION_TO_OS_ID.get(self.mariner_version, DEFAULT_VERSION_ID),
Version=self.mariner_version,
),
)

def vulnerability_id(self, definition: Definition) -> str | None:
Expand Down Expand Up @@ -223,6 +227,22 @@ def vulnerabilities(self) -> Generator[Vulnerability, None, None]:
}


# All values are based off of the ID value within /etc/os-release
# e.g.:
# docker run --rm -it mcr.microsoft.com/azurelinux/base/core:3.0 cat /etc/os-release | grep ID
# ID=azurelinux
# ...
#
# docker run --rm -it mcr.microsoft.com/cbl-mariner/base/core:2.0.20220731-arm64@sha256:51101e635f56032d5afd3fb cat /etc/os-release | grep ID
# ID=mariner
# ...
DEFAULT_VERSION_ID = "azurelinux"
VERSION_TO_OS_ID = {
"1.0": "mariner",
"2.0": "mariner",
}


class Parser:
def __init__(self, workspace: Workspace, download_timeout: int, allow_versions: list[Any], logger: logging.Logger):
self.workspace = workspace
Expand Down
Loading
Loading
0