Skip to content

Avoid .NET Standard 1.x dependencies in core stack repositories #13315

@ViktorHofer

Description

@ViktorHofer

Just recently, many of our core stack repositories received Component Governance issues because of references to vulnerable package versions. Most warnings were mitigated by upgrading the transitive dependencies but repositories could actually avoid them all-together. Vulnerable dependencies are often transitively referenced via the NETStandard.Library package which is implicitly referenced when targeting or consuming netstandard1.x assets. Avoiding these dependencies minimizes an app's dependency graph which a) makes restore more efficient, b) avoids maintaining and updating package versions and c) reduces surface area for future vulnerabilities.

Example:

  • The System.Net.Http nuget package is referenced in many .NET Framework and .NETCoreApp builds in our stack.
  • That package hasn't been updated in years and all versions except the current (4.3.4) are marked as vulnerable.
  • With CG alerts, repositories decided to upgrade that dependency (which is referenced either directly or transitively) to the latest version. While that's a viable approach, it mitigates the current alert but doesn't help avoiding future alerts.

=> Better: As System.Net.Http.dll is inbox in both .NET Framework and .NETCoreApp, that package dependency can be avoided entirely.

  • If the dependency is referenced directly on .NETCoreApp, simply remove it. It's already referenced implicitly via the Microsoft.NETCore.App.Ref targeting pack.
  • If the dependency is referenced directly on .NETFramework, replace it with <Reference Include="System.Net.Http" /> which brings in the assembly from the .NET Framework installation (GAC).
  • If the dependency isn't directly referenced, check the app's project.assets.json file to find the dependency that brings it in transitively. Try to avoid that parent dependency by walking up the graph.

Arcade's FlagNetStandard1xDependencies switch validates that projects don't bring in the .NET Standard 1.x dependency graph which consists of de-facto deprecated and vulnerable packages. While some netstandard1.x dependencies can't be avoided, i.e. xunit doesn't provide a netstandard2.0 TFM and won't until v3 ships, most existing (transitive) dependencies can actually be avoided.

Eventually, by removing all netstandard1.x dependencies in at least the source build graph, we can remove the netstandard1.x targeting packs and package TFMs from the SBRP repository. That itself reduces source build's payload size (which our partners care about) and validates that the dependency graph is modern (based on the assumption that netstandard1.x assemblies are usually many years old).

The tables below track enabling that switch in our core stack repositories.

Part of the VMR

Repository Status Note
arcade bde465e, 16e645a, #13341, #14082
aspnetcore
cecil
command-line-api
deployment-tools
diagnostics
emsdk
format dotnet/format#1812
fsharp
installer
msbuild
nuget-client
razor
roslyn-analyzers
roslyn
runtime dotnet/runtime#85641, dotnet/runtime@32a16d0, dotnet/runtime@0b04dfd, dotnet/runtime#85701, dotnet/runtime#96795
sdk
source-build-externals
source-build-reference-packages
sourcelink dotnet/sourcelink@87da2ff, dotnet/sourcelink#1015
symreader dotnet/symreader@2c8079e
templating 🕘 dotnet/templating#6403
test-templates
vstest
xdt dotnet/xdt@fcff05d, dotnet/xdt@8b75ac1

Outside of the VMR

Repository Status Note

cc @ericstj @mmitche @MichaelSimons @SteveMCarroll

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions