CycloneDX / cyclonedx-dotnet

Creates CycloneDX Software Bill of Materials (SBOM) from .NET Projects
https://cyclonedx.org/
Apache License 2.0
185 stars 89 forks source link

SBOM for Unity-project created without any components #824

Closed mmarseu closed 10 months ago

mmarseu commented 10 months ago

I'm trying to create an SBOM for an application written in Unity and I'm not getting anywhere. I'm neither an expert on Unity, nor the .NET project structure, so I'd like to apologize in advance if this issue is not on your end.

Basically, an SBOM gets created but apart from the highest-level components making up the Unity project, it doesn't list any dependencies, notably none of Unity's own modules are listed, even tough the app obviously depends on them. When I build the app from within Unity, I see tons of Unity DLLs being copied into the artifact.

Here is what I understand of how Unity and .NET interact:

I've tried both project styles but neither lets cyclonedx-dotnet create a complete SBOM.

Here's my guess what's happening, but as I said, I don't know much about .NET projects are structured:
I saw that all references to Unity-provided modules are listed as <Reference> elements – not for instance <PackageReference> which is used for depending on Nuget packages. These <Reference>s basically only point the compiler to the location of the DLL to link against but they are not taken into account by cyclonedx-dotnet when computing the components included in the product.

Do you see any way to generate a complete SBOM from these project files or is the way Unity generates the files simply not suited for SBOM-generation and therefore we'll have to push for a Unity-aware CycloneDX generator?

The following are some samples of the project files created and what cyclonedx-dotnet makes of them.

Experiments done with:

Project style

Expand for a modified example of one of the .csproj files ("PathCreator.csproj") ```xml 9.0 Debug AnyCPU 10.0.20506 2.0 {98EE3B46-3F8A-9E9E-F8DA-10B78547BCB8} Library Properties PathCreator v4.7.1 512 . true full false Temp\bin\Debug\ UNITY_2021_3_29;UNITY_2021_3;UNITY_2021;UNITY_5_3_OR_NEWER;UNITY_5_4_OR_NEWER;UNITY_5_5_OR_NEWER;UNITY_5_6_OR_NEWER;UNITY_2017_1_OR_NEWER;UNITY_2017_2_OR_NEWER;UNITY_2017_3_OR_NEWER;UNITY_2017_4_OR_NEWER;UNITY_2018_1_OR_NEWER;UNITY_2018_2_OR_NEWER;UNITY_2018_3_OR_NEWER;UNITY_2018_4_OR_NEWER;UNITY_2019_1_OR_NEWER;UNITY_2019_2_OR_NEWER;UNITY_2019_3_OR_NEWER;UNITY_2019_4_OR_NEWER;UNITY_2020_1_OR_NEWER;UNITY_2020_2_OR_NEWER;UNITY_2020_3_OR_NEWER;UNITY_2021_1_OR_NEWER;UNITY_2021_2_OR_NEWER;UNITY_2021_3_OR_NEWER;PLATFORM_ARCH_64;UNITY_64;UNITY_INCLUDE_TESTS;ENABLE_AR;ENABLE_AUDIO;ENABLE_CACHING;ENABLE_CLOTH;ENABLE_EVENT_QUEUE;ENABLE_MICROPHONE;ENABLE_MULTIPLE_DISPLAYS;ENABLE_PHYSICS;ENABLE_TEXTURE_STREAMING;ENABLE_VIRTUALTEXTURING;ENABLE_UNET;ENABLE_LZMA;ENABLE_UNITYEVENTS;ENABLE_VR;ENABLE_WEBCAM;ENABLE_UNITYWEBREQUEST;ENABLE_WWW;ENABLE_CLOUD_SERVICES;ENABLE_CLOUD_SERVICES_ADS;ENABLE_CLOUD_SERVICES_USE_WEBREQUEST;ENABLE_CLOUD_SERVICES_CRASH_REPORTING;ENABLE_CLOUD_SERVICES_PURCHASING;ENABLE_CLOUD_SERVICES_ANALYTICS;ENABLE_CLOUD_SERVICES_UNET;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_CLOUD_LICENSE;ENABLE_EDITOR_HUB_LICENSE;ENABLE_WEBSOCKET_CLIENT;ENABLE_DIRECTOR_AUDIO;ENABLE_DIRECTOR_TEXTURE;ENABLE_MANAGED_JOBS;ENABLE_MANAGED_TRANSFORM_JOBS;ENABLE_MANAGED_ANIMATION_JOBS;ENABLE_MANAGED_AUDIO_JOBS;ENABLE_MANAGED_UNITYTLS;INCLUDE_DYNAMIC_GI;ENABLE_SCRIPTING_GC_WBARRIERS;PLATFORM_SUPPORTS_MONO;RENDER_SOFTWARE_CURSOR;ENABLE_VIDEO;ENABLE_ACCELERATOR_CLIENT_DEBUGGING;PLATFORM_STANDALONE;TEXTCORE_1_0_OR_NEWER;PLATFORM_STANDALONE_WIN;UNITY_STANDALONE_WIN;UNITY_STANDALONE;ENABLE_RUNTIME_GI;ENABLE_MOVIES;ENABLE_NETWORK;ENABLE_NVIDIA;ENABLE_CRUNCH_TEXTURE_COMPRESSION;ENABLE_UNITY_GAME_SERVICES_ANALYTICS_SUPPORT;ENABLE_OUT_OF_PROCESS_CRASH_HANDLER;ENABLE_CLUSTER_SYNC;ENABLE_CLUSTERINPUT;PLATFORM_UPDATES_TIME_OUTSIDE_OF_PLAYER_LOOP;GFXDEVICE_WAITFOREVENT_MESSAGEPUMP;ENABLE_WEBSOCKET_HOST;ENABLE_MONO;NET_STANDARD_2_0;NET_STANDARD;NET_STANDARD_2_1;NETSTANDARD;NETSTANDARD2_1;ENABLE_PROFILER;DEBUG;TRACE;UNITY_ASSERTIONS;UNITY_EDITOR;UNITY_EDITOR_64;UNITY_EDITOR_WIN;ENABLE_UNITY_COLLECTIONS_CHECKS;ENABLE_BURST_AOT;UNITY_TEAM_LICENSE;ENABLE_CUSTOM_RENDER_TEXTURE;ENABLE_DIRECTOR;ENABLE_LOCALIZATION;ENABLE_SPRITES;ENABLE_TERRAIN;ENABLE_TILEMAP;ENABLE_TIMELINE;ENABLE_INPUT_SYSTEM;ENABLE_LEGACY_INPUT_MANAGER;TEXTCORE_FONT_ENGINE_1_5_OR_NEWER;UNITY_POST_PROCESSING_STACK_V2;USE_INPUT_SYSTEM_POSE_CONTROL;CSHARP_7_OR_LATER;CSHARP_7_3_OR_NEWER prompt 4 0169;USG0001 False pdbonly true Temp\bin\Release\ prompt 4 0169;USG0001 False true true false false false {E097FAD1-6243-4DAD-9C02-E9B9EFC3FFC1};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} Package 2.0.22 Legacy Game:1 StandaloneWindows64:19 2021.3.29f1 C:\Program Files\Unity 2021.3.29f1\Editor\Data\Managed\UnityEngine\UnityEngine.dll False C:\Program Files\Unity 2021.3.29f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Web.dll False Library\ScriptAssemblies\UnityEngine.UI.dll False ```

Here's the output of dotnet-cyclonedx.exe:

C:\Users\morit\Downloads\vr00-getting-started> dotnet-CycloneDX.exe -j .\PathCreator.csproj

Found the following local nuget package cache locations:
    C:\Users\morit\.nuget\packages\
Scanning at C:\Users\morit\Downloads\vr00-getting-started\PathCreator.csproj

» Analyzing: C:\Users\morit\Downloads\vr00-getting-started\PathCreator.csproj
  Attempting to restore packages
  Packages restored
File not found: "C:\Users\morit\Downloads\vr00-getting-started\obj\project.assets.json", "C:\Users\morit\Downloads\vr00-getting-started\PathCreator.csproj"
  No packages found
Found 0 packages

Creating CycloneDX BOM
Writing to: C:\Users\morit\Downloads\vr00-getting-started\bom.json

From my research I gathered that project.asset.json might be generated elsewhere and that I can specify that location using the -biop parameter. Unfortunately, there is no project.asset.json anywhere in the project folder.

sdk-style

Expand for "PathCreator.csproj" ```xml Temp\obj\$(Configuration)\$(MSBuildProjectName) $(BaseIntermediateOutputPath) false false false 9.0 Debug;Release Debug AnyCPU Library Properties PathCreator netstandard2.1 . true full false Temp\bin\Debug\ UNITY_2021_3_29;UNITY_2021_3;UNITY_2021;UNITY_5_3_OR_NEWER;UNITY_5_4_OR_NEWER;UNITY_5_5_OR_NEWER;UNITY_5_6_OR_NEWER;UNITY_2017_1_OR_NEWER;UNITY_2017_2_OR_NEWER;UNITY_2017_3_OR_NEWER;UNITY_2017_4_OR_NEWER;UNITY_2018_1_OR_NEWER;UNITY_2018_2_OR_NEWER;UNITY_2018_3_OR_NEWER;UNITY_2018_4_OR_NEWER;UNITY_2019_1_OR_NEWER;UNITY_2019_2_OR_NEWER;UNITY_2019_3_OR_NEWER;UNITY_2019_4_OR_NEWER;UNITY_2020_1_OR_NEWER;UNITY_2020_2_OR_NEWER;UNITY_2020_3_OR_NEWER;UNITY_2021_1_OR_NEWER;UNITY_2021_2_OR_NEWER;UNITY_2021_3_OR_NEWER;PLATFORM_ARCH_64;UNITY_64;UNITY_INCLUDE_TESTS;ENABLE_AR;ENABLE_AUDIO;ENABLE_CACHING;ENABLE_CLOTH;ENABLE_EVENT_QUEUE;ENABLE_MICROPHONE;ENABLE_MULTIPLE_DISPLAYS;ENABLE_PHYSICS;ENABLE_TEXTURE_STREAMING;ENABLE_VIRTUALTEXTURING;ENABLE_UNET;ENABLE_LZMA;ENABLE_UNITYEVENTS;ENABLE_VR;ENABLE_WEBCAM;ENABLE_UNITYWEBREQUEST;ENABLE_WWW;ENABLE_CLOUD_SERVICES;ENABLE_CLOUD_SERVICES_ADS;ENABLE_CLOUD_SERVICES_USE_WEBREQUEST;ENABLE_CLOUD_SERVICES_CRASH_REPORTING;ENABLE_CLOUD_SERVICES_PURCHASING;ENABLE_CLOUD_SERVICES_ANALYTICS;ENABLE_CLOUD_SERVICES_UNET;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_CLOUD_LICENSE;ENABLE_EDITOR_HUB_LICENSE;ENABLE_WEBSOCKET_CLIENT;ENABLE_DIRECTOR_AUDIO;ENABLE_DIRECTOR_TEXTURE;ENABLE_MANAGED_JOBS;ENABLE_MANAGED_TRANSFORM_JOBS;ENABLE_MANAGED_ANIMATION_JOBS;ENABLE_MANAGED_AUDIO_JOBS;ENABLE_MANAGED_UNITYTLS;INCLUDE_DYNAMIC_GI;ENABLE_SCRIPTING_GC_WBARRIERS;PLATFORM_SUPPORTS_MONO;RENDER_SOFTWARE_CURSOR;ENABLE_VIDEO;ENABLE_ACCELERATOR_CLIENT_DEBUGGING;PLATFORM_STANDALONE;TEXTCORE_1_0_OR_NEWER;PLATFORM_STANDALONE_WIN;UNITY_STANDALONE_WIN;UNITY_STANDALONE;ENABLE_RUNTIME_GI;ENABLE_MOVIES;ENABLE_NETWORK;ENABLE_NVIDIA;ENABLE_CRUNCH_TEXTURE_COMPRESSION;ENABLE_UNITY_GAME_SERVICES_ANALYTICS_SUPPORT;ENABLE_OUT_OF_PROCESS_CRASH_HANDLER;ENABLE_CLUSTER_SYNC;ENABLE_CLUSTERINPUT;PLATFORM_UPDATES_TIME_OUTSIDE_OF_PLAYER_LOOP;GFXDEVICE_WAITFOREVENT_MESSAGEPUMP;ENABLE_WEBSOCKET_HOST;ENABLE_MONO;NET_STANDARD_2_0;NET_STANDARD;NET_STANDARD_2_1;NETSTANDARD;NETSTANDARD2_1;ENABLE_PROFILER;DEBUG;TRACE;UNITY_ASSERTIONS;UNITY_EDITOR;UNITY_EDITOR_64;UNITY_EDITOR_WIN;ENABLE_UNITY_COLLECTIONS_CHECKS;ENABLE_BURST_AOT;UNITY_TEAM_LICENSE;ENABLE_CUSTOM_RENDER_TEXTURE;ENABLE_DIRECTOR;ENABLE_LOCALIZATION;ENABLE_SPRITES;ENABLE_TERRAIN;ENABLE_TILEMAP;ENABLE_TIMELINE;ENABLE_INPUT_SYSTEM;ENABLE_LEGACY_INPUT_MANAGER;TEXTCORE_FONT_ENGINE_1_5_OR_NEWER;UNITY_POST_PROCESSING_STACK_V2;USE_INPUT_SYSTEM_POSE_CONTROL;CSHARP_7_OR_LATER;CSHARP_7_3_OR_NEWER prompt 4 0169;USG0001 False pdbonly true Temp\bin\Release\ prompt 4 0169;USG0001 False true true true true MSB3277 Package 2.0.22 SDK Game:1 StandaloneWindows64:19 2021.3.29f1 C:\Program Files\Unity 2021.3.29f1\Editor\Data\Managed\UnityEngine\UnityEngine.dll False C:\Program Files\Unity 2021.3.29f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Web.dll False Library\ScriptAssemblies\UnityEngine.UI.dll False ```

This time, at least a project.assets.json gets generated inside Temp\obj\PathCreator:

Expand for "project.assets.json" ```json { "version": 3, "targets": { ".NETStandard,Version=v2.1": {} }, "libraries": {}, "projectFileDependencyGroups": { ".NETStandard,Version=v2.1": [] }, "packageFolders": { "C:\\Users\\morit\\.nuget\\packages\\": {}, "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages": {} }, "project": { "version": "1.0.0", "restore": { "projectUniqueName": "C:\\Users\\morit\\Downloads\\vr00-getting-started\\PathCreator.csproj", "projectName": "PathCreator", "projectPath": "C:\\Users\\morit\\Downloads\\vr00-getting-started\\PathCreator.csproj", "packagesPath": "C:\\Users\\morit\\.nuget\\packages\\", "outputPath": "C:\\Users\\morit\\Downloads\\vr00-getting-started\\Temp\\obj\\\\PathCreator\\", "projectStyle": "PackageReference", "fallbackFolders": [ "C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages" ], "configFilePaths": [ "C:\\Users\\morit\\AppData\\Roaming\\NuGet\\NuGet.Config", "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config", "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" ], "originalTargetFrameworks": [ "netstandard2.1" ], "sources": { "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, "C:\\Program Files\\dotnet\\library-packs": {}, "https://api.nuget.org/v3/index.json": {} }, "frameworks": { "netstandard2.1": { "targetAlias": "netstandard2.1", "projectReferences": {} } }, "warningProperties": { "warnAsError": [ "NU1605" ] } }, "frameworks": { "netstandard2.1": { "targetAlias": "netstandard2.1", "imports": [ "net461", "net462", "net47", "net471", "net472", "net48", "net481" ], "assetTargetFallback": true, "warn": true, "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\8.0.100\\RuntimeIdentifierGraph.json" } } } } ```

The generator now runs without errors:

PS C:\Users\morit\Downloads\vr00-getting-started> dotnet-CycloneDX.exe -biop .\Temp -j .\PathCreator.csproj

Found the following local nuget package cache locations:
    C:\Users\morit\.nuget\packages\
Scanning at C:\Users\morit\Downloads\vr00-getting-started\PathCreator.csproj

» Analyzing: C:\Users\morit\Downloads\vr00-getting-started\PathCreator.csproj
  Attempting to restore packages
  Packages restored
  No packages found
Found 0 packages

Creating CycloneDX BOM
Writing to: C:\Users\morit\Downloads\vr00-getting-started\bom.json

The resulting SBOM still has zero components, though.

mtsfoni commented 10 months ago

Here's my guess what's happening, but as I said, I don't know much about .NET projects are structured: I saw that all references to Unity-provided modules are listed as elements – not for instance which is used for depending on Nuget packages. These s basically only point the compiler to the location of the DLL to link against but they are not taken into account by cyclonedx-dotnet when computing the components included in the product.

Do you see any way to generate a complete SBOM from these project files or is the way Unity generates the files simply not suited for SBOM-generation and therefore we'll have to push for a Unity-aware CycloneDX generator?

Originally, CycloneDX dotnet tool only supports NuGet-Packages. With Version 3.0 I also support Project-References (Other referenced projects in the same .sln).

Direct dependencies to .dlls are not yet supported. I have this planned for the 'near' future. I briefly checked the possibility for when making version 3.0 and think it's not a big effort to get them from the .csproj file. However, we may not have a lot of data to write into the SBOM for those dependencies (Filename as Componentname, maybe FileVersion as Version).

Related to: #79

mmarseu commented 10 months ago

Thank you for the quick response. Then I'm hopeful we'll be able to create SBOMs for our apps within the not-too-distant future.

Our own SBOM requirements will need more than just the DLL name and version but we have solutions in place to merge the missing info into the SBOM, once it is generated.

I've subscribed to #79 and will close this issue.

fhe35 commented 5 months ago

Hello, any updates on this issue? We currently face the same problem and #79 seems to be dormant too.

mtsfoni commented 5 months ago

Still in the backlog behind more urging matters.

Sorry

If it helps I am working on a tool that one could use to easily add a predefined component to a created sbom - I assume those all references don't change often and as mentioned, the information that could be read automatically are rather limited anyways.

mmarseu commented 5 months ago

If it helps I am working on a tool that one could use to easily add a predefined component to a created sbom - I assume those all references don't change often and as mentioned, the information that could be read automatically are rather limited anyways.

I'm not sure that's true in our case. This Unity-generated project contains hundreds of references, if I'm not mistaken and versions would probably change with every update of Unity.

fhe35 commented 5 months ago

Thanks for the quick reply. In our case some of the dlls do change quite often, others not so much. So we will also take the path of merging the missing information into the SBOM after initial creation.