anchore / vunnel

Tool for collecting vulnerability data from various sources (used to build the grype database)
Apache License 2.0
69 stars 25 forks source link

Potential missing CVE/package associations in database for SLES #655

Closed BenoitGui closed 1 month ago

BenoitGui commented 1 month ago

Steps to reproduce the issue Build sles database with: grype-db build -g -p sles Open database and compare with original oval. What happened: Some packages seems to be missing in database for specifics CVE on some systems. If we for example take CVE-2016-5440, we have in database: image However in the original oval file we have the two following criteria (both are in the same OR criteria for vuln CVE-2016-5440, timestamp of the oval: 2024-07-23T05:27:20, line 693181): image and image

What you expected to happen: Please indicate if i am wrong there, but the packages in the first criteria should also be inside the database. This issue lead to a quite significant number of missing packages/CVE associations in database, leading to potentially missing visibility on CVE on a system.

Anything else we need to know?: I did not tried to investigate where is the issue in the source code

Environment: grype-db version: 0.23.2 Seems to affect all SLES systems

spiffcs commented 1 month ago

👋 thanks for the issue @BenoitGui - you are correct that it seems some of the or entries are being skipped or not included on purpose (need to look at the SLES provider):

I looked in the DB and for all instances of libmysqlclient_r18 I could not find the 10.40... constraint added.

I've added a label here so that when we have some cycles we can come back and see why the SLES parsers is misbehaving and not parsing all of the OVAL data correctly. Thanks for the important find here!

BenoitGui commented 1 month ago

Thanks for the response ! Would it be possible to tell me where is the SLES OVAL is parsed in the code (or how it is parse) ? I could help you to find where is the issue if possible

spiffcs commented 1 month ago

Yep! It lives over in vunnel.

That runs the nightly job that builds the data for the final database:

You can see the individual data runs for sles here in github actions.

Grype DB is responsible for stitching those different provider results into the final grype database that gets published each day.

willmurphyscode commented 1 month ago

I also wanted to link this issue to a PR already opened in Vunnel: https://github.com/anchore/vunnel/pull/635 where we are changing which OVAL XML is ingested in the SLES provider.

The reason I mention it specifically is that switching to the -affected OVAL XML file is going to require some changes to the OVAL parsing anyway, so we should try to validate and fix this issue during that implementation.

willmurphyscode commented 1 month ago

@BenoitGui are you able to post a link to the XML file that is screenshotted in the original post? I'd like to be certain I'm trying to parse the same XML you are.

BenoitGui commented 1 month ago

Yes of course that's this oval : https://ftp.suse.com/pub/projects/security/oval/suse.linux.enterprise.server.12.xml (Fixed and not affected Vulnerabilities) . Unfortunately i updated the file on my system so i do not have the original file anymore. However the updated file from the suse oval repo still contains the same criterias for the same CVE, so that shouldn't be an issue and you should observe the same behavior. Thanks for the information @spiffcs , i am going to try to take a look at it.

BenoitGui commented 1 month ago

Udpate on the code: I found the issue location. We have the following code in the parser (line 290 to 332):


                    fixes.append(
                        FixedIn(
                            Name=pkg_name,
                            NamespaceName=feed_ns,
                            VersionFormat="rpm",
                            Version=pkg_version,
                            Module=None,
                            VendorAdvisory=None,
                        ),
                    )

                # create the normalized vulnerability
                feed_obj = Vulnerability(
                    Name=vulnerability_obj.name,
                    NamespaceName=feed_ns,
                    Description=vulnerability_obj.description,
                    Severity=vulnerability_obj.severity,
                    Link=vulnerability_obj.link,
                    CVSS=normalized_cvss_list,
                    FixedIn=fixes,
                )

                if release_version not in version_release_feed:
                    version_release_feed[release_version] = defaultdict(Vulnerability)

                version_release_feed[release_version][release_name] = feed_obj

            # resolve multiple normalized entries per version
            results.extend(cls._release_resolver(version_release_feed, vulnerability_obj.name))

            # free the contents
            version_release_feed.clear()

        return results

The line

                version_release_feed[release_version][release_name] = feed_obj

is crushing the old vulnerabilities. Indeed we have several impact_item with the same release_version and release_name for one vulnerability due to the OVAL syntax. Because of that, recreating a version_release_feed[release_version][release_name] is erasing the old fixes. I think i have a patch, if you want in can do a PR in the next few days.

spiffcs commented 1 month ago

Thanks @BenoitGui! @willmurphyscode the comment above might help if you're still in this section of vunnel as well.

willmurphyscode commented 1 month ago

Thanks much @BenoitGui! We would really appreciate a patch. Let me know if I can be of any help here.

BenoitGui commented 1 month ago

I did a PR at https://github.com/anchore/vunnel/pull/650. Thanks for the help @willmurphyscode and @spiffcs ! 😃 I let you close the issue when the PR will be merged