Grepping NuGet IDs

Now and then there are announcments about NuGet packages with known vulnerabilities. Like this recent announcement via Twitter (from @blowdart) and the annoncement repo (github.com/dotnet/announcements) .

Sadly, there’s no great way of checking or patching your .NET Core projects via the CLI or Visual Studio automatically. So to check if you’re affected, you need to check if you’re referencing an affected NuGet — either directly or indirectly (transient). Doing so today is a bit tedious by, since you need to search through your code base via string searches for NuGet ID’s. When that list ends up being 15–20 NuGets, you pretty much get bored after the first 3…Anyways, if you do want to go down that route — a pro tip is to make use of the project.assets.json file generated by dotnet restore. This file actually outputs transient as well as direct dependencies in one place.

Even though Microsoft (yet) hasn’t made a tool to automate this search, it doesn’t mean we cannot make one ourselves. In fact, the dotnet CLI extensibility model makes it very easy to make a re-useable tool for others. In short, all we need to do is

Create a .NET Core self contained app following a certain naming convention dotnet-toolname.dll Mark the project as a tool. Add PackageType>DotnetCliTool</PackageType> in a PropertyGroup in our csproj where all our nuspec-metadata now resides. Make it do what we want to: check for vulnerable references. Build, test, pack & publish to nuget.org

The result is a tool we can use by calling dotnet <toolname> . Following these steps, I created dotnet retire to do the scanning for me. The naming is of course heavily inspired by the very cool retire.js that does a similar job for JavaScript modules/libraries.

Usage

Execute it like any other .NET Core tool:

$ dotnet retire

Currently, it outputs if my project is affected — and if it’s affected via a direct dependency or transient dependency.

A next step could be to make it ask the user to update to a known fixed version, which is very much doable given that the announcements come with recommended versions we should upgrade to.

Installing

Edit: The install procedure below is now out of date. With the .NET SDK 2.1.400+, dotnet-retire has been migrated to a global tool. Install via:

dotnet tool install -g dotnet-retire

The .NET Core CLI does not support installing tool packages as of the time of writing (coming soon?), so we need to manually edit our csproj adding a DotNetCliToolReference . <ItemGroup>

<DotNetCliToolReference Include="dotnet-retire" Version="1.0.0-*" />

</ItemGroup>

Want to help out, have a feature request or caught a bug? Ping me at the GitHub issue tracker or @johnkors on Twitter.

Source: https://github.com/RetireNet/dotnet-retire

Tool package: https://www.nuget.org/packages/dotnet-retire

Data source for the tool: https://github.com/RetireNet/Packages/