I’m encountering an issue with Grype where the database entry for certain CVEs doesn’t align with the artifact details returned by Grype. For example, in CVE-2023-2953, the package name is listed as libldap-2_4-2 in the database, but the artifact Grype returns looks like this:
As you can see, the database uses libldap-2_4-2 while Grype returns libldap-2.4-2. This discrepancy is causing issues when I try to match records. Does anyone know why this mismatch is occurring or have any suggestions on how to handle it?
Grype gets artifacts by invoking Syft, which inspects the source being scanned (a container image, directory, archive, etc). So if the artifact’s name is libldap-2.4-2 in the scan results, it’s because in the image that’s what RPM or dpkg or whatever list as the name of the thing installed. libldap-2_4-2 is the name in the database because that’s the name that some vulnerability provider published. It’s possible for the people who published the CVE and the people who published the software to disagree on how to name it.
This situation is one of the reasons that we consider the best source for vulnerability matching to be the distro-specific vulnerability feed for the image being scanned. For example, if Debian or Ubuntu or Red Hat publish CVE-2023-2953 in their vulnerability data, and also publish a libldab dpkg or rpm, they are likely to use the same package name for in both places. One of the challenges with NVD’s data is that the strings in the CPE are made up by NVD or whoever submitted the CVE there, and so might have this sort of name mismatch.
(It’s also possible we have a bug somewhere, but I don’t have enough information yet to speak to that.)
Are you scanning an image? If so, make sure Grype is identifying the Linux distro it is built from correctly. For example:
Which looks right. If Grype is wrong about the distro, you can try passing --distro name:version to it, which will help it compare the right package names. (Also, if that fixes your issue, please open an issue against Syft that we’re mis-identifying a distro).
Beyond that, I don’t really have any suggestions without more information about the scan being performed. Can you share a minimal Dockerfile that reproduces the issue? Can you tell me what kind of artifact you are scanning (I assume an image)? Can you tell me what distro the image is built from?
Right now, I’m working with the Grype database directly rather than scanning a specific image. I’ve set up a database from Grype’s data and am using package names in the database to match and display vulnerability information based on the artifact object. While working on this, I noticed the inconsistency between package names in the database (like libldap-2_4-2) and what Grype identifies in the artifact object (libldap-2.4-2), so I wanted to understand if there was an underlying reason for this mismatch.
I don’t currently have a specific Docker image or real-world case to reproduce this issue in a scan context, though I may look into finding one to test. For now, though, this is just based on what I observed in the Grype DB.
Thanks again for helping clarify how these names might differ due to data sources and package naming.
Can I ask one more question related to this thread?
I’ve noticed that some results from Grype include CVEs and package names that don’t appear in the main vulnerability table. Is it possible for Grype to return matches like this? If so, could you explain the logic or matching process behind it? Feel free to point me to the relevant code or just give a brief explanation.
Thanks!
Update:
I think i found the missing info it’s in Syft, it’s the upstream matching, can i still get more info about it?
You’re right, this is probably upstream matching. Many vulnerability providers report vulnerabilities against a source RPM for example. This match type will be listed as exact-indirect-match in Grype’s JSON output: this means that the package Syft found has as its source RPM a vulnerable package.
You can see more information about these matches by piping Grype’s JSON output into grype explain like this: