DependencyTrack / hyades

Incubating project for decoupling responsibilities from Dependency-Track's monolithic API server into separate, scalable services.
https://dependencytrack.github.io/hyades/latest
Apache License 2.0
60 stars 18 forks source link

Parsing of `vers` ranges is broken #732

Closed nscuro closed 1 year ago

nscuro commented 1 year ago

The API server fails to properly parse vers version ranges from records in the dtrack.vulnerability topic.

When encountering a vers range like vers:generic/2.6.0|2.6.17.9, the parsing logic assumes that the range is not definite, and skips it.

It does however still create a VulnerableSoftware record on this case, but it does so without any version information at all. What should happen instead, is that no record will be created at all. At the moment, this behavior causes duplicate VulnerableSoftware records, because multiple ranges end up with identical VulnerableSoftware representations.

Example BOV
{
    "specVersion": "",
    "components": [
        {
            "type": "CLASSIFICATION_NULL",
            "bomRef": "9940b488-1bc7-4ccb-8ee1-5e6681241ca8",
            "name": "",
            "version": "",
            "hashes": [],
            "licenses": [],
            "cpe": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
            "externalReferences": [],
            "components": [],
            "properties": [],
            "evidence": []
        },
        {
            "type": "CLASSIFICATION_NULL",
            "bomRef": "23da8df8-599c-42ec-8bea-456f2f5ae518",
            "name": "",
            "version": "",
            "hashes": [],
            "licenses": [],
            "cpe": "cpe:2.3:o:canonical:ubuntu_linux:5.04:*:*:*:*:*:*:*",
            "externalReferences": [],
            "components": [],
            "properties": [],
            "evidence": []
        },
        {
            "type": "CLASSIFICATION_NULL",
            "bomRef": "0aace0e6-9aeb-494f-90d4-6ff7b09cf593",
            "name": "",
            "version": "",
            "hashes": [],
            "licenses": [],
            "cpe": "cpe:2.3:o:canonical:ubuntu_linux:5.10:*:*:*:*:*:*:*",
            "externalReferences": [],
            "components": [],
            "properties": [],
            "evidence": []
        },
        {
            "type": "CLASSIFICATION_NULL",
            "bomRef": "dcbf174b-a2a9-40d3-a907-3c2a262828bd",
            "name": "",
            "version": "",
            "hashes": [],
            "licenses": [],
            "cpe": "cpe:2.3:o:canonical:ubuntu_linux:6.06:*:*:*:lts:*:*:*",
            "externalReferences": [],
            "components": [],
            "properties": [],
            "evidence": []
        },
        {
            "type": "CLASSIFICATION_NULL",
            "bomRef": "50498ba9-813a-4dac-bdb2-01f90c4ad830",
            "name": "",
            "version": "",
            "hashes": [],
            "licenses": [],
            "cpe": "cpe:2.3:o:debian:debian_linux:3.1:*:*:*:*:*:*:*",
            "externalReferences": [],
            "components": [],
            "properties": [],
            "evidence": []
        }
    ],
    "services": [],
    "externalReferences": [
        {
            "type": "EXTERNAL_REFERENCE_TYPE_OTHER",
            "url": "http://kernel.org/pub/linux/kernel/v2.4/ChangeLog-2.4.33.1",
            "hashes": []
        },
        {
            "type": "EXTERNAL_REFERENCE_TYPE_OTHER",
            "url": "http://kernel.org/pub/linux/kernel/v2.6/ChangeLog-2.6.17.9",
            "hashes": []
        },
        {
            "type": "EXTERNAL_REFERENCE_TYPE_OTHER",
            "url": "http://secunia.com/advisories/21563",
            "hashes": []
        },
        {
            "type": "EXTERNAL_REFERENCE_TYPE_OTHER",
            "url": "http://secunia.com/advisories/21695",
            "hashes": []
        },
        {
            "type": "EXTERNAL_REFERENCE_TYPE_OTHER",
            "url": "http://secunia.com/advisories/21847",
            "hashes": []
        },
        {
            "type": "EXTERNAL_REFERENCE_TYPE_OTHER",
            "url": "http://secunia.com/advisories/21934",
            "hashes": []
        },
        {
            "type": "EXTERNAL_REFERENCE_TYPE_OTHER",
            "url": "http://secunia.com/advisories/22093",
            "hashes": []
        },
        {
            "type": "EXTERNAL_REFERENCE_TYPE_OTHER",
            "url": "http://secunia.com/advisories/22148",
            "hashes": []
        },
        {
            "type": "EXTERNAL_REFERENCE_TYPE_OTHER",
            "url": "http://secunia.com/advisories/22292",
            "hashes": []
        },
        {
            "type": "EXTERNAL_REFERENCE_TYPE_OTHER",
            "url": "http://secunia.com/advisories/22945",
            "hashes": []
        },
        {
            "type": "EXTERNAL_REFERENCE_TYPE_OTHER",
            "url": "http://support.avaya.com/elmodocs2/security/ASA-2006-249.htm",
            "hashes": []
        },
        {
            "type": "EXTERNAL_REFERENCE_TYPE_OTHER",
            "url": "http://www.debian.org/security/2006/dsa-1184",
            "hashes": []
        },
        {
            "type": "EXTERNAL_REFERENCE_TYPE_OTHER",
            "url": "http://www.debian.org/security/2006/dsa-1237",
            "hashes": []
        },
        {
            "type": "EXTERNAL_REFERENCE_TYPE_OTHER",
            "url": "http://www.novell.com/linux/security/advisories/2006_21_sr.html",
            "hashes": []
        },
        {
            "type": "EXTERNAL_REFERENCE_TYPE_OTHER",
            "url": "http://www.novell.com/linux/security/advisories/2006_22_sr.html",
            "hashes": []
        },
        {
            "type": "EXTERNAL_REFERENCE_TYPE_OTHER",
            "url": "http://www.novell.com/linux/security/advisories/2006_57_kernel.html",
            "hashes": []
        },
        {
            "type": "EXTERNAL_REFERENCE_TYPE_OTHER",
            "url": "http://www.redhat.com/support/errata/RHSA-2006-0689.html",
            "hashes": []
        },
        {
            "type": "EXTERNAL_REFERENCE_TYPE_OTHER",
            "url": "http://www.securityfocus.com/bid/19615",
            "hashes": []
        },
        {
            "type": "EXTERNAL_REFERENCE_TYPE_OTHER",
            "url": "http://www.ubuntu.com/usn/usn-346-1",
            "hashes": []
        },
        {
            "type": "EXTERNAL_REFERENCE_TYPE_OTHER",
            "url": "http://www.vupen.com/english/advisories/2006/3330",
            "hashes": []
        },
        {
            "type": "EXTERNAL_REFERENCE_TYPE_OTHER",
            "url": "http://www.vupen.com/english/advisories/2006/3331",
            "hashes": []
        },
        {
            "type": "EXTERNAL_REFERENCE_TYPE_OTHER",
            "url": "https://issues.rpath.com/browse/RPL-611",
            "hashes": []
        },
        {
            "type": "EXTERNAL_REFERENCE_TYPE_OTHER",
            "url": "https://oval.cisecurity.org/repository/search/definition/oval%3Aorg.mitre.oval%3Adef%3A10666",
            "hashes": []
        }
    ],
    "dependencies": [],
    "compositions": [],
    "vulnerabilities": [
        {
            "id": "CVE-2006-4093",
            "source": {
                "name": "NVD"
            },
            "references": [],
            "ratings": [
                {
                    "score": 4.9,
                    "severity": "SEVERITY_MEDIUM",
                    "method": "SCORE_METHOD_CVSSV2",
                    "vector": "AV:L/AC:L/Au:N/C:N/I:N/A:C"
                }
            ],
            "cwes": [],
            "description": "Linux kernel 2.x.6 before 2.6.17.9 and 2.4.x before 2.4.33.1 on PowerPC PPC970 systems allows local users to cause a denial of service (crash) related to the \"HID0 attention enable on PPC970 at boot time.\"",
            "advisories": [],
            "published": "2006-08-21T21:04:00Z",
            "updated": "2018-10-17T17:00:27Z",
            "tools": [],
            "affects": [
                {
                    "ref": "9940b488-1bc7-4ccb-8ee1-5e6681241ca8",
                    "versions": [
                        {
                            "range": "vers:generic/2.4.0|2.4.33.1"
                        }
                    ]
                },
                {
                    "ref": "9940b488-1bc7-4ccb-8ee1-5e6681241ca8",
                    "versions": [
                        {
                            "range": "vers:generic/2.6.0|2.6.17.9"
                        }
                    ]
                },
                {
                    "ref": "23da8df8-599c-42ec-8bea-456f2f5ae518",
                    "versions": []
                },
                {
                    "ref": "0aace0e6-9aeb-494f-90d4-6ff7b09cf593",
                    "versions": []
                },
                {
                    "ref": "dcbf174b-a2a9-40d3-a907-3c2a262828bd",
                    "versions": []
                },
                {
                    "ref": "50498ba9-813a-4dac-bdb2-01f90c4ad830",
                    "versions": []
                }
            ],
            "properties": []
        }
    ]
}

In a unit test, the above BOV ends up creating the following VulnerableSoftware records:

VulnerableSoftware{id=1, purl='null', purlType='null', purlNamespace='null', purlName='null', purlVersion='null', purlQualifiers='null', purlSubpath='null', cpe22='cpe:/o:linux:linux_kernel', cpe23='cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*', part='o', vendor='linux', product='linux_kernel', version='*', update='*', edition='*', language='*', swEdition='*', targetSw='*', targetHw='*', other='*', versionEndExcluding='null', versionEndIncluding='null', versionStartExcluding='null', versionStartIncluding='null', vulnerable=true, vulnerabilities=[org.dependencytrack.model.Vulnerability@257d3968], uuid=8d23f145-e8dc-474a-adfc-04c9ec404477, affectedVersionAttributions=null}
VulnerableSoftware{id=2, purl='null', purlType='null', purlNamespace='null', purlName='null', purlVersion='null', purlQualifiers='null', purlSubpath='null', cpe22='cpe:/o:linux:linux_kernel', cpe23='cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*', part='o', vendor='linux', product='linux_kernel', version='*', update='*', edition='*', language='*', swEdition='*', targetSw='*', targetHw='*', other='*', versionEndExcluding='null', versionEndIncluding='null', versionStartExcluding='null', versionStartIncluding='null', vulnerable=true, vulnerabilities=[org.dependencytrack.model.Vulnerability@257d3968], uuid=9ea4953a-7c8b-45cd-95e9-d6b55b9347f8, affectedVersionAttributions=null}

Beside their ID and UUID, they are identical. Also note how the BOV contains 4 additional CPEs that were not parsed, and for which the affected.versions node is empty for some reason.

nscuro commented 1 year ago

The algorithm for vers parsing is defined here: https://github.com/package-url/purl-spec/blob/version-range-spec/VERSION-RANGE-SPEC.rst#parsing-and-validating-version-range-specifiers

nscuro commented 1 year ago

Seems the incoming data (produced by mirror-service) is incorrect.

vers:generic/2.4.0|2.4.33.1 says "Version 2.4.0 and 2.4.33.1 are affected", but according to the CPEs it should be "Versions >= 2.4.0 and < 2.4.33.1 are affected".

image

So it should've been a vers range like vers:generic/>=2.4.0|<2.4.33.1 instead (see https://github.com/package-url/purl-spec/blob/version-range-spec/VERSION-RANGE-SPEC.rst#version-constraint).

Raised #733 to revisit the parsing on the mirror-service side of things.