Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrong CPEs generated for OpenSSL by dotnet cataloguer #3120

Open
tomasr opened this issue Aug 13, 2024 · 4 comments
Open

Wrong CPEs generated for OpenSSL by dotnet cataloguer #3120

tomasr opened this issue Aug 13, 2024 · 4 comments
Labels
bug Something isn't working

Comments

@tomasr
Copy link

tomasr commented Aug 13, 2024

What happened:

Using Syft to scan a folder that contains a mix of .NET libraries as well as native windows libraries.

The native windows libraries include OpenSSL components (libssl-3-x64.dll and libcrypto-3-x64.dll).

When scanning the libraries, the generated SBOM has output like this:

{
	"id": "1b62f6a35b4be69d",
	"name": "The OpenSSL Toolkit",
	"version": "3.0.8",
	"type": "dotnet",
	"foundBy": "dotnet-portable-executable-cataloger",
	"locations": [
		{
			"path": "\\libssl-3-x64.dll",
			"accessPath": "\\libssl-3-x64.dll",
			"annotations": {
				"evidence": "primary"
			}
		}
	],
	"licenses": [
	],
	"language": "dotnet",
	"cpes": [
		{
			"cpe": "cpe:2.3:a:The_OpenSSL_Toolkit:The_OpenSSL_Toolkit:3.0.8:*:*:*:*:*:*:*",
			"source": "syft-generated"
		}
	],
	"purl": "pkg:nuget/The%20OpenSSL%[email protected]",
	"metadataType": "dotnet-portable-executable-entry",
	"metadata": {
		"assemblyVersion": "",
		"legalCopyright": "Copyright 1998-2024 The OpenSSL Authors. All rights reserved.",
		"internalName": "libssl",
		"companyName": "The OpenSSL Project, https://www.openssl.org/",
		"productName": "The OpenSSL Toolkit",
		"productVersion": "3.0.8"
	}
},

Notice the CPE cpe:2.3:a:The_OpenSSL_Toolkit:The_OpenSSL_Toolkit:3.0.8:*:*:*:*:*:*:*. Notice the name is The_OpenSSL_Toolkit which seems to be based on the Product Name field in the resources of the library:

image

This will lead to other tools (like grype) being unable to actually match these to any known vulnerabilities.

What you expected to happen:

Using the right CPEs would let these be matched: cpe:2.3:a:openssl:openssl:3.0.8:*:*:*:*:*:*:*.

Unfortunately, I'm not quite sure how you'd figure that out just from the library information available, but I suspect a more general class of this issue is that the dotnet cataloger sort of assumes everything is a .net assembly and not arbitrary native Windows libraries that could be present (and there doesn't seem to be any other cataloger available that would handle native windows binaries in general).

Steps to reproduce the issue:

  • Download this nuget package
  • Rename to zip and extract
  • Run syft on the extracted directory

Anything else we need to know?:

Environment:

  • Output of syft version: 1.11
  • OS (e.g: cat /etc/os-release or similar): Windows 11
@tomasr tomasr added the bug Something isn't working label Aug 13, 2024
@spiffcs
Copy link
Contributor

spiffcs commented Aug 14, 2024

👋 thanks for the good repro steps @tomasr - when we get some cycles I think the best first step is to see if we can read more from that libssl-3-x64.dll file to see if there is any additional metadata that would help inform us which cpe needs to be generated.

Currently we extract these fields:

		AssemblyVersion: versionResources["Assembly Version"],
		LegalCopyright:  versionResources["LegalCopyright"],
		Comments:        versionResources["Comments"],
		InternalName:    versionResources["InternalName"],
		CompanyName:     versionResources["CompanyName"],
		ProductName:     versionResources["ProductName"],
		ProductVersion:  versionResources["ProductVersion"],

func buildDotNetPackage(versionResources map[string]string, f file.LocationReadCloser) (dnpkg pkg.Package, err error) {
name := findName(versionResources)
if name == "" {
return dnpkg, fmt.Errorf("unable to find PE name in file: %s", f.RealPath)
}
version := findVersion(versionResources)
if version == "" {
return dnpkg, fmt.Errorf("unable to find PE version in file: %s", f.RealPath)
}
metadata := pkg.DotnetPortableExecutableEntry{
AssemblyVersion: versionResources["Assembly Version"],
LegalCopyright: versionResources["LegalCopyright"],
Comments: versionResources["Comments"],
InternalName: versionResources["InternalName"],
CompanyName: versionResources["CompanyName"],
ProductName: versionResources["ProductName"],
ProductVersion: versionResources["ProductVersion"],
}
dnpkg = pkg.Package{
Name: name,
Version: version,
Locations: file.NewLocationSet(f.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)),
Type: pkg.DotnetPkg,
Language: pkg.Dotnet,
PURL: portableExecutablePackageURL(name, version),
Metadata: metadata,
}
dnpkg.SetID()
return dnpkg, nil
}

How I see it is that, not specific to the nuget cataloger, but if ANY cataloger runs into a file with the .dll extension then there is some shared syft logic that can inspect that to help inform the greater package creation regardless of which ecosystem is being scanned.

Do you have an example of a vulnerability you think this SHOULD match against so we have a target cpe you think is correct to generate?

@spiffcs spiffcs moved this to Ready in OSS Aug 14, 2024
@popey
Copy link
Contributor

popey commented Aug 14, 2024

Interestingly exiftool does show the metadata in that library, so it's in an 'easily' accessible location, if we wanted to grub around for it. "openssl" isn't there, as a specific entry.

$ exiftool ./runtimes/win-x64/native/libssl-3-x64.dll
ExifTool Version Number         : 12.76
File Name                       : libssl-3-x64.dll
File Size                       : 548 kB
File Modification Date/Time     : 2024:07:10 13:38:30+01:00
File Access Date/Time           : 2024:08:14 15:15:37+01:00
File Inode Change Date/Time     : 2024:08:14 15:14:40+01:00
File Permissions                : -rw-rw-r--
File Type                       : Win64 DLL
File Type Extension             : dll
MIME Type                       : application/octet-stream
Machine Type                    : AMD AMD64
Time Stamp                      : 2024:07:10 14:34:11+01:00
Image File Characteristics      : Executable, Large address aware, DLL
PE Type                         : PE32+
Linker Version                  : 14.29
Code Size                       : 368128
Initialized Data Size           : 180224
Uninitialized Data Size         : 0
Entry Point                     : 0x5a5a0
OS Version                      : 6.0
Image Version                   : 0.0
Subsystem Version               : 6.0
Subsystem                       : Windows GUI
File Version Number             : 3.0.8.0
Product Version Number          : 3.0.8.0
File Flags Mask                 : 0x003f
File Flags                      : (none)
File OS                         : Win32
Object File Type                : Dynamic link library
File Subtype                    : 0
Language Code                   : English (U.S.)
Character Set                   : Unicode
Company Name                    : The OpenSSL Project, https://www.openssl.org/
File Description                : OpenSSL library
File Version                    : 3.0.8
Internal Name                   : libssl
Original File Name              : libssl
Product Name                    : The OpenSSL Toolkit
Product Version                 : 3.0.8
Legal Copyright                 : Copyright 1998-2024 The OpenSSL Authors. All rights reserved.

@tomasr
Copy link
Author

tomasr commented Aug 14, 2024

@spiffcs

Do you have an example of a vulnerability you think this SHOULD match against so we have a target cpe you think is correct to generate?

Once I put the right CPEs in place (i.e. with just openssl), I get these from grype:

NAME                 INSTALLED  FIXED-IN  TYPE    VULNERABILITY   SEVERITY
The OpenSSL Toolkit  3.0.8                dotnet  CVE-2024-5535   Critical
The OpenSSL Toolkit  3.0.8                dotnet  CVE-2023-5363   High
The OpenSSL Toolkit  3.0.8                dotnet  CVE-2023-4807   High
The OpenSSL Toolkit  3.0.8                dotnet  CVE-2023-0464   High
The OpenSSL Toolkit  3.0.8                dotnet  CVE-2024-0727   Medium
The OpenSSL Toolkit  3.0.8                dotnet  CVE-2023-6129   Medium
The OpenSSL Toolkit  3.0.8                dotnet  CVE-2023-5678   Medium
The OpenSSL Toolkit  3.0.8                dotnet  CVE-2023-3817   Medium
The OpenSSL Toolkit  3.0.8                dotnet  CVE-2023-2975   Medium
The OpenSSL Toolkit  3.0.8                dotnet  CVE-2023-2650   Medium
The OpenSSL Toolkit  3.0.8                dotnet  CVE-2023-1255   Medium
The OpenSSL Toolkit  3.0.8                dotnet  CVE-2023-0466   Medium
The OpenSSL Toolkit  3.0.8                dotnet  CVE-2023-0465   Medium
The OpenSSL Toolkit  3.0.8                dotnet  CVE-2024-4603   Unknown
The OpenSSL Toolkit  3.0.8                dotnet  CVE-2024-2511   Unknown
The OpenSSL Toolkit  3.0.8                dotnet  CVE-2023-6237   Unknown

Which match what we've seen from other scanners.

@spiffcs
Copy link
Contributor

spiffcs commented Aug 15, 2024

Awesome! Ok we talked about this during our livestream:
https://www.youtube.com/watch?v=m0wG_LQUhPo

I think what we're going to do here is move away from cpe generation for cataloger/packages here by trying to derive it from the metadata.

Instead, the metadata here IS stable enough that we can build a key from it and then get pre-crafted correct cpes from our dictionary solution here:
https://github.com/anchore/syft/tree/main/syft/pkg/cataloger/internal/cpegenerate

When we get some cycles someone from the team will pick it up and move us away from generating these junk CPE for packages coming form this cataloger.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
Status: Ready
Development

No branches or pull requests

3 participants