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
Incorrect package name and purl of dotnet nuget packages #2697
Comments
Same for syft 1.0.1 |
"\packages\Microsoft.Exchange.WebServices.2.2\lib\40\Microsoft.Exchange.WebServices.dll" |
Additional Information: This assembies are .Net Framework 4.x, not .NetCode or .Net6/7/8. |
Thanks @markusmuellerusi for the report, we will take a look as soon as we can. |
Hey @markusmuellerusi, we've done a bunch of digging here and it looks as though the dll files inside that package have some bad metadata, probably from Microsoft's own build process. We are seeing We suspect that in this case, there is some failed template interpolation going on. We have found that Nuget packages don't really have a standard field name for the package name, unfortunately. We have a heuristic to choose which field to use for the package name, and for most Microsoft-built packages, Do you by chance have a support agreement with Microsoft at all? Have you seen this sort of behavior on any other Nuget packages? We'll be happy to try to work out a solution. |
I think it would be better for this kind of project to analyze the packages.config instead of the files (.dll). Here's a snippet created with CycloneDx-dotnet-tool:
It uses the packages.config file I can use the "syft:location:" property to search for matching package in that path. |
packages.config file |
< ?xml version="1.0" encoding="utf-8"? > |
Thanks for the hints, @markusmuellerusi, this is very helpful. Can you help me understand where packages.config fits in a bit better? I unzipped the |
For .Net4.x projects, the packages.config file may be located in the project directory, at the same level as the .csproj file itself. The packages directory may be located in the top-level solutions directory. .Net 6/7/8 projects do not have a separate configuration file, the package references are included in the .csproj file. But it all depends on what kind of setup for the package you want to use. (use within the project or for the solution or globally and use package reference). This task may not be easy to determine. |
For folks looking to reproduce the issue: $ dotnet new console
$ dotnet add package Microsoft.Exchange.WebServices --version 2.2.0
$ dotnet publish -c Release
$ syft . -o table -o json=sbom.json
✔ Indexed file system .
✔ Cataloged contents cdb4ee2aea69cc6a83331bbe96dc2caa9a299d21329efb0336fc02a82e1839a8
├── ✔ Packages [16 packages]
└── ✔ Executables [16 executables]
NAME VERSION TYPE
Microsoft.Exchange.WebServices 2.2.0 dotnet (+1 duplicate)
f#InternalName 15.00.0913.015 dotnet (+1 duplicate)
p(InternalName 15.00.0913.000 dotnet (+1 duplicate)
...
{
"id": "18551e301b570224",
"name": "f#InternalName",
"version": "15.00.0913.015",
"type": "dotnet",
"foundBy": "dotnet-portable-executable-cataloger",
"locations": [
{
"path": "/bin/Release/net7.0/Microsoft.Exchange.WebServices.dll",
"accessPath": "/bin/Release/net7.0/Microsoft.Exchange.WebServices.dll",
"annotations": {
"evidence": "primary"
}
}
],
"licenses": [],
"language": "dotnet",
"cpes": [
{
"cpe": "cpe:2.3:a:f\\#InternalName:f\\#InternalName:15.00.0913.015:*:*:*:*:*:*:*",
"source": "syft-generated"
}
],
"purl": "pkg:nuget/f%23InternalName@15.00.0913.015",
"metadataType": "dotnet-portable-executable-entry",
"metadata": {
"assemblyVersion": "",
"legalCopyright": "© 2014 Microsoft Corporation. All rights reserved.",
"comments": "Service Pack 0",
"internalName": "Microsoft.Exchange.WebServices.dll",
"companyName": "Microsoft Corporation",
"productName": "Microsoft® Exchange",
"productVersion": "15.00.0913.015"
}
}
{
"id": "683c8944d460183a",
"name": "f#InternalName",
"version": "15.00.0913.015",
"type": "dotnet",
"foundBy": "dotnet-portable-executable-cataloger",
"locations": [
{
"path": "/bin/Release/net7.0/publish/Microsoft.Exchange.WebServices.dll",
"accessPath": "/bin/Release/net7.0/publish/Microsoft.Exchange.WebServices.dll",
"annotations": {
"evidence": "primary"
}
}
],
"licenses": [],
"language": "dotnet",
"cpes": [
{
"cpe": "cpe:2.3:a:f\\#InternalName:f\\#InternalName:15.00.0913.015:*:*:*:*:*:*:*",
"source": "syft-generated"
}
],
"purl": "pkg:nuget/f%23InternalName@15.00.0913.015",
"metadataType": "dotnet-portable-executable-entry",
"metadata": {
"assemblyVersion": "",
"legalCopyright": "© 2014 Microsoft Corporation. All rights reserved.",
"comments": "Service Pack 0",
"internalName": "Microsoft.Exchange.WebServices.dll",
"companyName": "Microsoft Corporation",
"productName": "Microsoft® Exchange",
"productVersion": "15.00.0913.015"
}
}
{
"id": "7a319297af858a94",
"name": "p(InternalName",
"version": "15.00.0913.000",
"type": "dotnet",
"foundBy": "dotnet-portable-executable-cataloger",
"locations": [
{
"path": "/bin/Release/net7.0/Microsoft.Exchange.WebServices.Auth.dll",
"accessPath": "/bin/Release/net7.0/Microsoft.Exchange.WebServices.Auth.dll",
"annotations": {
"evidence": "primary"
}
}
],
"licenses": [],
"language": "dotnet",
"cpes": [
{
"cpe": "cpe:2.3:a:p\\(InternalName:p\\(InternalName:15.00.0913.000:*:*:*:*:*:*:*",
"source": "syft-generated"
}
],
"purl": "pkg:nuget/p(InternalName@15.00.0913.000",
"metadataType": "dotnet-portable-executable-entry",
"metadata": {
"assemblyVersion": "",
"legalCopyright": "© 2014 Microsoft Corporation. All rights reserved.",
"comments": "Service Pack 0",
"internalName": "Microsoft.Exchange.WebServices.Auth.dll",
"companyName": "Microsoft Corporation",
"productName": "Microsoft® Exchange",
"productVersion": "15.00.0913.000"
}
}
{
"id": "5a0ac610c16eb8f8",
"name": "p(InternalName",
"version": "15.00.0913.000",
"type": "dotnet",
"foundBy": "dotnet-portable-executable-cataloger",
"locations": [
{
"path": "/bin/Release/net7.0/publish/Microsoft.Exchange.WebServices.Auth.dll",
"accessPath": "/bin/Release/net7.0/publish/Microsoft.Exchange.WebServices.Auth.dll",
"annotations": {
"evidence": "primary"
}
}
],
"licenses": [],
"language": "dotnet",
"cpes": [
{
"cpe": "cpe:2.3:a:p\\(InternalName:p\\(InternalName:15.00.0913.000:*:*:*:*:*:*:*",
"source": "syft-generated"
}
],
"purl": "pkg:nuget/p(InternalName@15.00.0913.000",
"metadataType": "dotnet-portable-executable-entry",
"metadata": {
"assemblyVersion": "",
"legalCopyright": "© 2014 Microsoft Corporation. All rights reserved.",
"comments": "Service Pack 0",
"internalName": "Microsoft.Exchange.WebServices.Auth.dll",
"companyName": "Microsoft Corporation",
"productName": "Microsoft® Exchange",
"productVersion": "15.00.0913.000"
}
} |
I think it's a pretty good guess. I don't think having a An initial look shows we can probably add this "fix" safely. |
Though the downside with using this "indirect" value is that they appear to lead to incorrect versions relative to the package manager (nuget in this case): v15.00.0913.000 vs v2.2
In the context of the incorrect values described in this issue I think this makes sense, but there is more nuance there when it comes to parsing manifest-like files. This is a little more confusing since .NET core vs .NET have different ways to track project dependencies (package.config vs .csproj). There are also some trade offs. Let's take a simple project as an example:
Taking a look at the manifest, we will see only direct dependencies ( <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<RootNamespace>syft_2697</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Exchange.WebServices" Version="2.2.0" />
<PackageReference Include="System.Text.Json" Version="8.0.3" />
</ItemGroup>
</Project> (I'm using dotnet v7) This trade off is not the case when looking at the deps.json contents{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v7.0",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v7.0": {
"syft-2697/1.0.0": {
"dependencies": {
"Microsoft.Exchange.WebServices": "2.2.0",
"System.Text.Json": "8.0.3"
},
"runtime": {
"syft-2697.dll": {}
}
},
"Microsoft.Exchange.WebServices/2.2.0": {
"runtime": {
"lib/40/Microsoft.Exchange.WebServices.Auth.dll": {
"assemblyVersion": "15.0.0.0",
"fileVersion": "15.0.913.0"
},
"lib/40/Microsoft.Exchange.WebServices.dll": {
"assemblyVersion": "15.0.0.0",
"fileVersion": "15.0.913.15"
}
}
},
"System.Text.Encodings.Web/8.0.0": {
"runtime": {
"lib/net7.0/System.Text.Encodings.Web.dll": {
"assemblyVersion": "8.0.0.0",
"fileVersion": "8.0.23.53103"
}
},
"runtimeTargets": {
"runtimes/browser/lib/net7.0/System.Text.Encodings.Web.dll": {
"rid": "browser",
"assetType": "runtime",
"assemblyVersion": "8.0.0.0",
"fileVersion": "8.0.23.53103"
}
}
},
"System.Text.Json/8.0.3": {
"dependencies": {
"System.Text.Encodings.Web": "8.0.0"
},
"runtime": {
"lib/net7.0/System.Text.Json.dll": {
"assemblyVersion": "8.0.0.0",
"fileVersion": "8.0.324.11423"
}
}
}
}
},
"libraries": {
"syft-2697/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Microsoft.Exchange.WebServices/2.2.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-NlkaTD0uWtg9VbiWq0VDWMBPzHFknH3tmstrxt0acrT09LBGqATTjRpsGOODz6tUdX7/dehBinxsf75U5Uw/+A==",
"path": "microsoft.exchange.webservices/2.2.0",
"hashPath": "microsoft.exchange.webservices.2.2.0.nupkg.sha512"
},
"System.Text.Encodings.Web/8.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ==",
"path": "system.text.encodings.web/8.0.0",
"hashPath": "system.text.encodings.web.8.0.0.nupkg.sha512"
},
"System.Text.Json/8.0.3": {
"type": "package",
"serviceable": true,
"sha512": "sha512-hpagS9joOwv6efWfrMmV9MjQXpiXZH72PgN067Ysfr6AWMSD1/1hEcvh/U5mUpPLezEWsOJSuVrmqDIVD958iA==",
"path": "system.text.json/8.0.3",
"hashPath": "system.text.json.8.0.3.nupkg.sha512"
}
}
} (this tradeoff also does not exist with the binary version resources section, but the deps.json is easier to read) In cases where there is only the binary and not the deps.json file, we also want to be accurate. I think there are changes that can be made to the PE cataloger to do that:
{
"id": "23eccff6e0f78092",
"name": "System.Text.Json",
"version": "8.0.324.11423",
"metadata": {
"productVersion": "8.0.3+9f4b1f5d664afdfc80e1508ab7ed099dff210fbd",
"fileVersion": "8.0.324.11423",
"fileDescription": "System.Text.Json",
}
}
{
"id": "0244a7a163f7c50e",
"name": "System.Text.Json",
"version": "8.0.324.11423",
"metadataType": "dotnet-portable-executable-entry",
"metadata": {
"productVersion": "8.0.3+9f4b1f5d664afdfc80e1508ab7ed099dff210fbd",
"fileVersion": "8.0.324.11423",
"fileDescription": "System.Text.Json",
}
} full json```json { "id": "23eccff6e0f78092", "name": "System.Text.Json", "version": "8.0.324.11423", "type": "dotnet", "foundBy": "dotnet-portable-executable-cataloger", "locations": [ { "path": "/Release/net7.0/System.Text.Json.dll", "accessPath": "/Release/net7.0/System.Text.Json.dll", "annotations": { "evidence": "primary" } } ], "licenses": [], "language": "dotnet", "cpes": [ { "cpe": "cpe:2.3:a:System.Text.Json:System.Text.Json:8.0.324.11423:*:*:*:*:*:*:*", "source": "syft-generated" } ], "purl": "pkg:nuget/System.Text.Json@8.0.324.11423", "metadataType": "dotnet-portable-executable-entry", "metadata": { "assemblyVersion": "8.0.0.0", "legalCopyright": "© Microsoft Corporation. All rights reserved.", "comments": "Provides high-performance and low-allocating types that serialize objects to JavaScript Object Notation (JSON) text and deserialize JSON text to objects, with UTF-8 support built-in. Also provides types to read and write JSON text encoded as UTF-8, and to create an in-memory document object model (DOM), that is read-only, for random access of the JSON elements within a structured view of the data.\r\n\r\nThe System.Text.Json library is built-in as part of the shared framework in .NET Runtime. The package can be installed when you need to use it in other target frameworks.", "internalName": "System.Text.Json.dll", "companyName": "Microsoft Corporation", "productName": "Microsoft® .NET", "productVersion": "8.0.3+9f4b1f5d664afdfc80e1508ab7ed099dff210fbd", "fileVersion": "8.0.324.11423", "fileDescription": "System.Text.Json", "originalFilename": "System.Text.Json.dll" } } { "id": "0244a7a163f7c50e", "name": "System.Text.Json", "version": "8.0.324.11423", "type": "dotnet", "foundBy": "dotnet-portable-executable-cataloger", "locations": [ { "path": "/Release/net7.0/publish/System.Text.Json.dll", "accessPath": "/Release/net7.0/publish/System.Text.Json.dll", "annotations": { "evidence": "primary" } } ], "licenses": [], "language": "dotnet", "cpes": [ { "cpe": "cpe:2.3:a:System.Text.Json:System.Text.Json:8.0.324.11423:*:*:*:*:*:*:*", "source": "syft-generated" } ], "purl": "pkg:nuget/System.Text.Json@8.0.324.11423", "metadataType": "dotnet-portable-executable-entry", "metadata": { "assemblyVersion": "8.0.0.0", "legalCopyright": "© Microsoft Corporation. All rights reserved.", "comments": "Provides high-performance and low-allocating types that serialize objects to JavaScript Object Notation (JSON) text and deserialize JSON text to objects, with UTF-8 support built-in. Also provides types to read and write JSON text encoded as UTF-8, and to create an in-memory document object model (DOM), that is read-only, for random access of the JSON elements within a structured view of the data.\r\n\r\nThe System.Text.Json library is built-in as part of the shared framework in .NET Runtime. The package can be installed when you need to use it in other target frameworks.", "internalName": "System.Text.Json.dll", "companyName": "Microsoft Corporation", "productName": "Microsoft® .NET", "productVersion": "8.0.3+9f4b1f5d664afdfc80e1508ab7ed099dff210fbd", "fileVersion": "8.0.324.11423", "fileDescription": "System.Text.Json", "originalFilename": "System.Text.Json.dll" } } ```For these examples it looks like the better version to be using is Additionally, maybe the PE cataloger should be deduplicating (merging really) these packages so that only one is shown. |
What happened:
Package name and purl do not match expectet result. Found
f#internalName
:What you expected to happen:
The name should be
Microsoft.Exchange.WebServices
and same for purlSteps to reproduce the issue:
Create an SBoM for a dotnet project using this nuget package:
Microsoft.Exchange.WebServices.2.2.nupkg
packages\Microsoft.Exchange.WebServices.2.2\lib\40\Microsoft.Exchange.WebServices.dll
Anything else we need to know?:
Environment:
syft version
: 0.104.0cat /etc/os-release
or similar): Windows 10 ProfThe text was updated successfully, but these errors were encountered: