예제 #1
0
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(
        vulnerability_id=vuln_id,
        summary=summary,
        impacted_package_urls=impacted_packages,
        resolved_package_urls=resolved_packages,
        references=references,
    )
    def collect_packages(self):
        packages = set()
        files = self._updated_files.union(self._added_files)
        for f in files:
            data = load_yaml(f)
            if data.get("package"):
                packages.add(data["package"])

        return packages
예제 #3
0
    def process_file(self, path) -> List[Advisory]:
        record = load_yaml(path)
        package_name = record.get("gem")

        if not package_name:
            return

        if "cve" in record:
            cve_id = "CVE-{}".format(record["cve"])
        else:
            return

        safe_version_ranges = record.get("patched_versions", [])
        # this case happens when the advisory contain only 'patched_versions' field
        # and it has value None(i.e it is empty :( ).
        if not safe_version_ranges:
            safe_version_ranges = []
        safe_version_ranges += record.get("unaffected_versions", [])
        safe_version_ranges = [i for i in safe_version_ranges if i]

        if not getattr(self, "pkg_manager_api", None):
            self.pkg_manager_api = RubyVersionAPI()
        all_vers = self.pkg_manager_api.get(package_name)
        safe_versions, affected_versions = self.categorize_versions(
            all_vers, safe_version_ranges)

        impacted_purls = {
            PackageURL(
                name=package_name,
                type="gem",
                version=version,
            )
            for version in affected_versions
        }

        resolved_purls = {
            PackageURL(
                name=package_name,
                type="gem",
                version=version,
            )
            for version in safe_versions
        }

        references = []
        if record.get("url"):
            references.append(Reference(url=record.get("url")))

        return Advisory(
            summary=record.get("description", ""),
            impacted_package_urls=impacted_purls,
            resolved_package_urls=resolved_purls,
            references=references,
            vulnerability_id=cve_id,
        )
예제 #4
0
    def process_file(self, path):
        yaml_file = load_yaml(path)
        pkg_name = yaml_file["package"]
        safe_pkg_versions = []
        vuln_pkg_versions = []
        if not yaml_file.get("patched_versions"):
            yaml_file["patched_versions"] = []

        if not yaml_file.get("unaffected_versions"):
            yaml_file["unaffected_versions"] = []

        safe_pkg_versions, vuln_pkg_versions = self.get_versions_for_pkg_from_range_list(
            yaml_file["patched_versions"] + yaml_file["unaffected_versions"],
            pkg_name,
        )

        if yaml_file.get("cve"):
            cve_id = "CVE-" + yaml_file["cve"]
        else:
            cve_id = ""

        safe_purls = []
        vuln_purls = []

        safe_purls = [
            PackageURL(name=pkg_name, type="hex", version=version) for version in safe_pkg_versions
        ]

        vuln_purls = [
            PackageURL(name=pkg_name, type="hex", version=version) for version in vuln_pkg_versions
        ]

        references = [
            Reference(
                reference_id=yaml_file["id"],
            ),
            Reference(
                url=yaml_file["link"],
            ),
        ]

        return Advisory(
            summary=yaml_file["description"],
            affected_packages=nearest_patched_package(vuln_purls, safe_purls),
            vulnerability_id=cve_id,
            references=references,
        )
    def test_to_advisory(self):
        raw_data = load_yaml(TEST_DATA)
        expected_data = [
            Advisory(
                summary="",
                references=[
                    Reference(
                        reference_id="",
                        url=
                        "https://ftp.suse.com/pub/projects/security/yaml/suse-cvss-scores.yaml",
                        severities=[
                            VulnerabilitySeverity(
                                system=ScoringSystem(
                                    identifier="cvssv2",
                                    name="CVSSv2 Base Score",
                                    url="https://www.first.org/cvss/v2/",
                                    notes="cvssv2 base score",
                                ),
                                value="4.3",
                            ),
                            VulnerabilitySeverity(
                                system=ScoringSystem(
                                    identifier="cvssv2_vector",
                                    name="CVSSv2 Vector",
                                    url="https://www.first.org/cvss/v2/",
                                    notes=
                                    "cvssv2 vector, used to get additional info about nature and severity of vulnerability",  # nopep8
                                ),
                                value="AV:N/AC:M/Au:N/C:N/I:N/A:P",
                            ),
                            VulnerabilitySeverity(
                                system=ScoringSystem(
                                    identifier="cvssv3.1",
                                    name="CVSSv3.1 Base Score",
                                    url="https://www.first.org/cvss/v3-1/",
                                    notes="cvssv3.1 base score",
                                ),
                                value="3.7",
                            ),
                            VulnerabilitySeverity(
                                system=ScoringSystem(
                                    identifier="cvssv3.1_vector",
                                    name="CVSSv3.1 Vector",
                                    url="https://www.first.org/cvss/v3-1/",
                                    notes=
                                    "cvssv3.1 vector, used to get additional info about nature and severity of vulnerability",  # nopep8
                                ),
                                value=
                                "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L",
                            ),
                        ],
                    )
                ],
                vulnerability_id="CVE-2004-0230",
            ),
            Advisory(
                summary="",
                references=[
                    Reference(
                        reference_id="",
                        url=
                        "https://ftp.suse.com/pub/projects/security/yaml/suse-cvss-scores.yaml",
                        severities=[
                            VulnerabilitySeverity(
                                system=ScoringSystem(
                                    identifier="cvssv3",
                                    name="CVSSv3 Base Score",
                                    url="https://www.first.org/cvss/v3-0/",
                                    notes="cvssv3 base score",
                                ),
                                value="8.6",
                            ),
                            VulnerabilitySeverity(
                                system=ScoringSystem(
                                    identifier="cvssv3_vector",
                                    name="CVSSv3 Vector",
                                    url="https://www.first.org/cvss/v3-0/",
                                    notes=
                                    "cvssv3 vector, used to get additional info about nature and severity of vulnerability",  # nopep8
                                ),
                                value=
                                "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N",
                            ),
                        ],
                    )
                ],
                vulnerability_id="CVE-2003-1605",
            ),
        ]

        found_data = SUSESeverityScoreDataSource.to_advisory(raw_data)
        found_advisories = list(map(Advisory.normalized, found_data))
        expected_advisories = list(map(Advisory.normalized, expected_data))
        assert sorted(found_advisories) == sorted(expected_advisories)