This post describes .NET NuGet library servicing support in the .NET Framework 4.5.1. It was written by Alok Shriram, a Program Manager on the .NET Core Framework Team.
In the .NET Framework 4.5.1, we extended our .NET Framework security update capability to our NuGet libraries, enabling us to deliver security updates for those libraries on Microsoft Update (MU). The update experience is the same one you are used to when we deliver security updates for the .NET Framework. Microsoft Update enables us to deliver security updates quickly and globally, in one way, for both end-users and enterprise customers.
Over the last couple of years, we’ve adopted NuGet as a .NET framework release vehicle, as a platform for quick publishing and community feedback. We know that enterprise (and other) customers rely on Microsoft Update to distribute security updates within their Windows desktop and server environments, efficiently and at scale. So, it wasn’t surprising that we heard requests to extend that centralized update model on Windows to the .NET NuGet packages that they include in their .NET Framework desktop and server apps. That support has been added to the .NET Framework 4.5.1.
The following points outline the policy that we intend to use with this new capability .
- This mechanism is going to be used only for targeted security updates. Any new features, Bug-fixes, reliability updates to existing packages will be published only to NuGet.
- No breaking changes will be delivered via this mechanism.
- Only vulnerable versions of an assembly will be fixed.
We will make security updates available via Microsoft Update and NuGet.org. You can proactively update your apps via NuGet.org or wait for updates to come down from MU. You get to choose. We will post security update notifications to the .NET blog.
Supported and Serviceable Libraries
A couple months ago, we announced that the Microsoft .NET NuGet libraries have the same support and servicing level as the .NET Framework. The servicing experience for those libraries is the topic of this post.
This set of libraries is described in a curated feed that the .NET team maintains. The NuGet client also supports this feed, as you can see below.
The experience of referencing and using .NET NuGet packages in Visual Studio is unchanged. NuGet library servicing is a characteristic of the .NET Framework 4.5.1, and is always enabled.
The experience of using a .NET app is also unchanged. The app will either load the .NET NuGet library that came with the app, or a serviced version that was installed by Microsoft Update.
The only noticeable indication that a security update has been downloaded and installed by Microsoft Update is by the Windows Update menus, as illustrated in the image below. The image shows a test .NET NuGet library that we used to validate the new experience.
How are the .NET NuGet libraries serviced?
NuGet libraries are deployed with your app. This is different from the .NET Framework, which is installed and updated on a per-machine basis. The per-app installation model used by NuGet required some new approaches to enable the same servicing experience as the .NET Framework.
There are two primary aspects to servicing a library with Microsoft Update:
- Determining that a machine is a candidate for an update
- Installing the update in a machine-wide location
The CLR identifies Microsoft published NuGet libraries via a special custom attribute created for this purpose. When a library with this attribute is loaded, the CLR records the load event as a marker on the machine, specifically the full assembly name. The marker information never leaves the machine, nor is it sent to Microsoft in any form.
At the point that we release a security update for a NuGet library, Microsoft Update will use the presence of the marker for that library as an indication that a given machine is a candidate for that update. The check for markers is done on the client machine. Markers that don’t have an associated security update are never consulted or used.
Microsoft Update installs updated assemblies into the Global Assembly Cache (GAC), to make them available to all users and apps on the machine that use a given .NET NuGet library. The update includes publisher policy, which is also installed to the GAC. Publisher policy redirects older, vulnerable, versions of libraries to new, updated, versions. The policy is intended to be as targeted as possible, and will not apply to older versions that are not vulnerable, since that is not necessary.
Example of NuGet Library Security Update
The following image is from an app from our test lab that was used to demonstrate this feature. You can see that it attempts to load the DotnetNuGetAssembly assembly, of version “220.127.116.11”. This assembly is a test assembly that is mimicking the behavior of our .NET NuGet libraries. Before the app was run, we serviced DotnetNuGetAssembly with an updated version via Microsoft Update. At runtime, the test app loads DotnetNuGetAssembly, version “18.104.22.168”, from the GAC, instead of the vulnerable app-local version. This example demonstrates the behavior that your app would experience at runtime should we need to service a .NET NuGet library that your app uses.
Our test app uses reflection to demonstrate this feature, in order to highlight the version number requested. You do not need to use reflection to take advantage of servicing via Microsoft Update.
Frequently Asked Questions
What kinds of updates to NuGet libraries will be pushed using Microsoft Update?
Only a serious security issue in a library in the curated feed will be updated using this mechanism. Even in this context only versions of the library that have the issue will be updated to the fixed version.
Does this mean that Microsoft NuGet dependencies will be updated automatically?
No. The primary way to get feature updates and bug fixes is via the NuGet package update experience. Our packages have the same update workflow as all other NuGet packages. We like the flexibility of app-local distribution of NuGet libraries, giving you the opportunity to choose the versions that work best for your app.
Can the update break my application?
No. Fixes will be targeted and the goal is to not break compatibility after a fix.
Does this mean that Microsoft Update will deploy my Microsoft NuGet dependencies when I deploy my app?
No. Visual Studio already deploys NuGet libraries to your bin folder when you build your app.
What kinds of library updates will I (or my customers) get from Microsoft Update?
We will only use Microsoft Update to patch .NET NuGet libraries in the case of security issues.
If you service a library via Microsoft Update, will you still update the library on NuGet.org?
Yes. NuGet.org is our primary release vehicle for NuGet updates, independent of whether an update is delivered via Microsoft Update.
Do you expect to service NuGet libraries via Microsoft Update often?
I saw a recent update to a .NET NuGet library that was not shipped this way. Why?
We are in the process of transitioning to this new update model.
Are only Stable libraries supported and serviceable?
That’s right. Only stable libraries are supported and serviceable. Prerelease libraries are provided so that you can give us feedback before we release them stable, at which point they become harder to change, since they are then supported!
I have a popular library on NuGet. Can I also use this feature?
No. Microsoft Update is only for Microsoft libraries.
What if my version of an affected library does not have the security issue?
The feature allows us to target specific versions of libraries. For instance if version 22.214.171.124 is vulnerable and 126.96.36.199 is not, we will only patch 188.8.131.52 to a fixed version.
Can I avoid requiring a Microsoft Update for my customers?
Yes. You can deploy the latest version of a library available on NuGet to avoid your customers needing any MU updates that have been released up until that point. We will post security update release announcements to this blog, to provide you with insight into which libraries have been patched.
How does Microsoft Update know that I have a vulnerable library?
We built a feature in the Common Language Runtime (CLR) that can identify if a library is a serviceable .NET NuGet library, via the presence of an assembly-level custom attribute. The CLR records the load event of the library so that the Microsoft Update client-side logic can use it when detecting applicable updates.
What exactly does patching involve?
When we detect a vulnerable version of a library on a machine, Microsoft Update will install a fixed version of the library with a higher version number into the GAC along with publisher policy to forward vulnerable versions of the assembly to the fixed version in the GAC. At runtime, vulnerable copies of a library will be automatically directed to the central fixed version.
What do I need to do to opt-in the Microsoft NuGet library servicing?
This is a feature of the .NET Framework 4.5.1. Your app needs to run on that version, or later. This implies that it will only work on Windows Vista and higher versions of the OS.
.NET NuGet library servicing is an important new feature in the .NET Framework 4.5.1. The NuGet libraries that we can update are the set described by our .NET NuGet feed. This is the same feed that is exposed as “Microsoft and .NET” in the NuGet client in Visual Studio. NuGet.org remains our primary release vehicle, however, we are glad to have this new capability, which allows for broad and quick deployment of security updates.
Please tell us what you think of this new capability. Is it a feature that is important to you? Please share your feedback in the comments below.