diff --git a/vulnerabilities/data_source.py b/vulnerabilities/data_source.py index 091b72394..44604f298 100644 --- a/vulnerabilities/data_source.py +++ b/vulnerabilities/data_source.py @@ -345,7 +345,7 @@ def _ensure_repository(self) -> None: def _clone_repository(self) -> None: kwargs = {} - if getattr(self, 'branch', False): + if self.config.branch: kwargs['checkout_branch'] = self.config.branch self._repo = pygit2.clone_repository( diff --git a/vulnerabilities/importer_yielder.py b/vulnerabilities/importer_yielder.py index 192d173dd..97dff6191 100644 --- a/vulnerabilities/importer_yielder.py +++ b/vulnerabilities/importer_yielder.py @@ -184,13 +184,23 @@ }, { 'name': 'msr2019', - 'license': '', + 'license': 'apache-2.0', 'last_run': None, 'data_source': 'ProjectKBMSRDataSource', 'data_source_cfg': { 'etag': {} }, }, + { + 'name': 'kaybee', + 'license': 'apache-2.0', + 'last_run': None, + 'data_source': 'KaybeeDataSource', + 'data_source_cfg': { + 'repository_url': 'https://github.com/SAP/project-kb.git', + 'branch': 'vulnerability-data' + }, + }, ] diff --git a/vulnerabilities/importers/__init__.py b/vulnerabilities/importers/__init__.py index c41a0b279..9b40f6449 100644 --- a/vulnerabilities/importers/__init__.py +++ b/vulnerabilities/importers/__init__.py @@ -39,3 +39,4 @@ from vulnerabilities.importers.github import GitHubAPIDataSource from vulnerabilities.importers.nvd import NVDDataSource from vulnerabilities.importers.project_kb_msr2019 import ProjectKBMSRDataSource +from vulnerabilities.importers.kaybee import KaybeeDataSource diff --git a/vulnerabilities/importers/kaybee.py b/vulnerabilities/importers/kaybee.py new file mode 100644 index 000000000..c317d52ce --- /dev/null +++ b/vulnerabilities/importers/kaybee.py @@ -0,0 +1,84 @@ +# Copyright (c) nexB Inc. and others. All rights reserved. +# http://nexb.com and https://github.com/nexB/vulnerablecode/ +# The VulnerableCode software is licensed under the Apache License version 2.0. +# Data generated with VulnerableCode require an acknowledgment. +# +# You may not use this software except in compliance with the License. +# You may obtain a copy of the License at: http://apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# +# When you publish or redistribute any data created with VulnerableCode or any VulnerableCode +# derivative work, you must accompany this data with the following acknowledgment: +# +# Generated with VulnerableCode and provided on an "AS IS" BASIS, WITHOUT WARRANTIES +# OR CONDITIONS OF ANY KIND, either express or implied. No content created from +# VulnerableCode should be considered or used as legal advice. Consult an Attorney +# for any legal advice. +# VulnerableCode is a free software tool from nexB Inc. and others. +# Visit https://github.com/nexB/vulnerablecode/ for support and download. + +import yaml + +from packageurl import PackageURL + +from vulnerabilities.data_source import GitDataSource +from vulnerabilities.data_source import Advisory +from vulnerabilities.data_source import Reference + + +class KaybeeDataSource(GitDataSource): + def __enter__(self): + super(KaybeeDataSource, self).__enter__() + self._added_files, self._updated_files = self.file_changes( + recursive=True, + file_ext="yaml", + ) + print(self._added_files.union(self._updated_files)) + + def updated_advisories(self): + advisories = [] + for yaml_file in self._added_files.union(self._updated_files): + print(yaml_file) + advisories.append(yaml_file_to_advisory(yaml_file)) + print(advisories[-1]) + + return self.batch_advisories(advisories) + + +def yaml_file_to_advisory(yaml_path): + impacted_packages = [] + resolved_packages = [] + references = [] + + data = load_yaml(yaml_path) + vuln_id = data["vulnerability_id"] + summary = "\n".join([note["text"] for note in data["notes"]]) + + for entry in data.get("artifacts", []): + package = PackageURL.from_string(entry["id"]) + if entry["affected"]: + impacted_packages.append(package) + + else: + resolved_packages.append(package) + + for fix in data.get("fixes", []): + for commit in fix["commits"]: + references.append(Reference(url=f"{commit['repository']}/{commit['id']}")) + + return Advisory( + cve_id=vuln_id, + summary=summary, + impacted_package_urls=impacted_packages, + resolved_package_urls=resolved_packages, + vuln_references=references, + ) + + +# TODO refactor all such commonly needed helpers into one single module +def load_yaml(path): + with open(path) as f: + return yaml.safe_load(f)