trivy: NET6 CVE-2019-0980 CVE-2019-0981 - possible bug in .deps.json trans deps resolution

Hi,

we are running NET6 images , but we get this 2019 vulnerability reported when running our trivy scans.

is this actually expected or could it be a false positive?

atm we added

CVE-2019-0980 CVE-2019-0981

but we cannot detect the source of the vulnerability after we updated all our packages

System.Private.Uri │ CVE-2019-0980 │ HIGH     │ 4.3.0             │ 4.3.2   

i am not sure we actually use this package, i see it not appearing at all after running

dotnet build and then dotnet publish and checking the .deps.json file

i think the recently introduced support for .deps.json might be buggy?

image

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 10
  • Comments: 44

Most upvoted comments

@DmitriyLewen My example clearly shows that the container is using version 6.0.922.41905 of System.Private.Uri not 4.3.0. Just because a version is in the .deps.json does not mean it the version actually in use. The *.deps.json method used by trivy may work for directly referenced packages but can’t be used universally for everything in the *.deps.json. I am not familiar enough to suggest how this should work but the existing approach is definitely incorrect.

@DmitriyLewen I don’t know enough about the deps.json to suggest the best way to do this. You would need to get feedback from someone on the dotnet team.

A potential improvement to the current would be to check the if the file exists in the same folder as the deps.json file. That would let you know the file is being provided by the app instead of the runtime (although not foolproof as the loading behavior can be customized). I did experiment and published the same app using a self-contained deployment the assembly version of System.Private.Uri in the deps.json file was set to 6.0.0.0 and file version to 6.0.422.16404 so it appears that it will show the correct version if it is including it in the deployment. For assemblies the runtime is supposed to provide (non self-contained) it must put the lowest compatible version or something similar into the deps.json which is what is triggering the false positive from aqua.

I also noticed it tags a fileVersion to anything it includes under the targets section of the deps.json so that may be able to be used to filter out assemblies provided by the runtime (if no fileVersion given) and shouldn’t be included in scans (assuming aqua validates the runtime version has no vulns).

I agree, the method of scanning deps.json for vulnerabilities is not valid, or at least needs some tweaking. We’re using the latest versions of System.Private.Uri included with .net 6 but aqua is flagging these containers as vulnerable:

/app $ cat <redacted>.deps.json | grep Uri
          "System.Private.Uri": "4.3.0"
      "runtime.unix.System.Private.Uri/4.3.0": {
          "System.Private.Uri": "4.3.0",
      "System.Private.Uri/4.3.0": {
          "runtime.unix.System.Private.Uri": "4.3.0"
    "runtime.unix.System.Private.Uri/4.3.0": {
    "System.Private.Uri/4.3.0": {

/app $ find / -name "*Uri*"
/usr/share/dotnet/shared/Microsoft.NETCore.App/6.0.9/System.Private.Uri.dll

/app $ exiftool /usr/share/dotnet/shared/Microsoft.NETCore.App/6.0.9/System.Private.Uri.dll | grep -w Version
ExifTool Version Number         : 12.40
Linker Version                  : 11.0
OS Version                      : 4.0
Image Version                   : 0.0
Subsystem Version               : 4.0
File Version Number             : 6.0.922.41905
Product Version Number          : 0.0.0.0
File Version                    : 6.0.922.41905
Product Version                 : 6.0.9-servicing.22419.5+163a63591cf9e9b682063cf3995948c2b885a042
Assembly Version                : 6.0.0.0

Very strange that the lock file does not contain System.Private.Uri It also doesn’t have runtime.any.System.Runtime and runtime.unix.System.Runtime.Extensions?

UPD: i installed dotnet add package runtime.unix.System.Runtime.Extensions --version 4.3.1 in my helloWorld project and lock file contains System.Private.Uri

UPD2: I also see some pattern - perhaps the version from System.Private.Uri.dll is the NetCore version, not System.Private.Uri version.

  1. ~The lock file is for direct / transitive package dependencies. System.Private.Uri is part of the runtime not a direct / transitive dependency~. It does not have to be referenced in a project to be used. edit: it appears that this is incorrect and the lock file does include the runtime packages under some circumstances, see @DmitriyLewen comments below

  2. You shouldn’t add those packages (including System.Private.Uri) to a project. Going to nuget we see the description of the package is Internal implementation package not meant for direct consumption. Please do not reference directly. Provides implementation of System.Uri.

  3. The core of the issue is the .deps.json does not universally tell you what version is in the container or what version will be used when the app is executed but trivy is treating it that way. dotnet uses a combination of the .deps.json and what assemblies are available to determine what is actually used. You can validate this by modifying values in the .deps.json to non-existent versions (or even deleting the file) and the app will usually run fine. The current behavior is to add in version 4.3.0 to the deps.json for the dependencies included by the dotnet runtime for --self-contained false published apps but I don’t see that documented anywhere and may change. As I mentioned before an improvement would be to only look at data in the deps.json that has a fileVersion but I wasn’t able to find documentation on when / why that is provided so may change as well.

The question then is: How would we separate those 2 checks?

As @plaisted mentioned: Maybe the solution to this is to indeed scan versions based on files included. This would work for both self-contained builds and the packages-only for regular builds:

I also noticed it tags a fileVersion to anything it includes under the targets section of the deps.json so that may be able to be used to filter out assemblies provided by the runtime (if no fileVersion given) and shouldn’t be included in scans (assuming aqua validates the runtime version has no vulns).

For regular builds, we would need to check the files without a fileversion in order to include the vulnerabilities present in the runtime

Bump. Until Trivy understands how .NET resolves transitive dependencies, Trivy is unusable for .NET projects.

@JoostvdB94 Perhaps i confused you. I meant that there is no information in the GitHub database that the framework has vulnerabilities (only in the description, but there are no rules for the description and we cannot parse it). Therefore, we cannot obtain information about vulnerabilities for frameworks.

I have installed several popular nuget packages, but my *deps.json file does not contain system/runtime packages. @JoostvdB94 @plaisted If you have ability, can you play with your projects and try to find package that adds System.Private.Uri.

The package that causes it in my case targets netcore1.1: https://www.nuget.org/packages/JsonDiffPatch

I think the lock file only specifies which packages it uses. Technically, the System.Private.Uri is not a package, as it is part of the dotnet runtime. That is why the .dll is present in self-contained builds, where the runtime does not need to be installed on the system that the app is running on, but the dll is missing in regular builds where the runtime needs to be installed on the system running the app.

In my opinion, we should treat both separately:

  • Scan for vulnerabilities in packages
  • Scan for vulnerabilities in the targeted framework version

The question then is: How would we separate those 2 checks?