BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News .NET 5 Breaking Changes to the Base Class Library

.NET 5 Breaking Changes to the Base Class Library

This item in japanese

Bookmarks

The upcoming release of .NET 5 introduces many breaking changes. While the vast majority of them involve edge cases or previously incorrect behavior, some may take developers by surprise. In the first of this multi-part series, InfoQ looks at the Base Class Library.

.NET Version Information

It may seem foolish, but a lot of developers have a bad habit of looking at the string representation of the version instead of the numeric form. This led to the infamous “Windows 9” story where Microsoft skipped from Windows 8 to Windows 10 to avoid problems in applications that were looking for Windows 95/98.

In the case of .NET, developers weren’t given a choice. Due in part to the odd numbering scheme, they had to rely on the string representation, looking for “.NET Framework #.#” or “.NET Core #.#”.

With .NET 5, the moniker is now simply “.NET #.#”. Applications and libraries that depend on detecting the runtime version will need to be updated.

OS Version Information

Previously, Environment.OSVersion could lie to the application. Rather than returning the actual OS version, it would return the emulated OS based on the Windows compatibility mode setting for the application. Microsoft explains,

Users of this property expect it to return the actual version of the operating system. Most .NET apps don't specify their supported version in their application manifest, and thus get the default supported version from the dotnet host. As a result, the compatibility shim is rarely meaningful for the app that's running. When Windows releases a new version and an older dotnet host is still in use, these apps may get an incorrect OS version. Returning the actual version is more inline with developers' expectations of this API.

File Location for Bundled Applications

When an application is bundled into a single file along with its dependencies, the behavior of some Reflection APIs are no longer obvious. Previously, bundled applications would have their dependencies extracted into a temporary location, so the Reflection calls would reference this. With .NET 5, those dependencies are loaded directly from memory. This means there is no physical Assembly file to reference. As such, the following APIs needed to be altered. Below are the new behaviors.

  • Assembly.Location: Returns empty string for bundled assemblies
  • Assembly.CodeBase: Throws exception for bundled assemblies
  • Assembly.GetFile(String): Throws exception for bundled assemblies
  • Environment.GetCommandLineArgs()[0]: Value is the name of the host executable
  • AppContext.BaseDirectory: Value is the containing directory of the host executable

Logging

The following ConsoleLoggerOptions have been marked as obsolete. They are replaced with one of several subclasses of ConsoleFormatterOptions.

  • ConsoleLoggerOptions.DisableColors
  • ConsoleLoggerOptions.IncludeScopes
  • ConsoleLoggerOptions.TimestampFormat
  • ConsoleLoggerOptions.UseUtcTimestamp
  • ConsoleLoggerOptions.Format

BinaryFormatter Serialization is Blocked

The BinaryFormatter for .NET’s serialization library has been around since the very beginning. The intention was for it to be faster and more compact than the XML-based SoapFormatter, which was shipped at the same time.

Unfortunately, it suffers from several problems, the most significant being it is impossible to use safely. Warnings from the BinaryFormatter security guide Microsoft include,

The BinaryFormatter.Deserialize method is never safe when used with untrusted input. We strongly recommend that consumers instead consider using one of the alternatives outlined later in this article.

and

We recommend that BinaryFormatter consumers perform individual risk assessments on their apps. It is the consumer's sole responsibility to determine whether to utilize BinaryFormatter. Consumers should risk assess the security, technical, reputation, legal, and regulatory requirements of using BinaryFormatter.

This is not the only serialization library that Microsoft considers unsafe. The following, while not as dangerous, should still be avoided because they are suspectable to unrestricted polymorphic deserialization.

  • SoapFormatter
  • LosFormatter
  • NetDataContractSerializer
  • ObjectStateFormatter

In .NET 5, BinaryFormatter is disabled by default in ASP.NET applications and produces a compiler warning for all other application frameworks. If you must use BinaryFormatter in a web site, you can reenable it via the EnableUnsafeBinaryFormatterSerialization flag.

UTF-7 is Blocked

Another blocked technology is UTF-7. This format is already forbidden in many standards such as HTML5. It is forbidden because it is easy to slip malicious strings into an application by tricking part of the application into thinking the data is in UTF-8 format while other parts correctly treat it as UTF-7.

Wikipedia elaborates,

UTF-7 allows multiple representations of the same source string. In particular, ASCII characters can be represented as part of Unicode blocks. As such, if standard ASCII-based escaping or validation processes are used on strings that may be later interpreted as UTF-7, then Unicode blocks may be used to slip malicious strings past them. To mitigate this problem, systems should perform decoding before validation and should avoid attempting to autodetect UTF-7.

Older versions of Internet Explorer can be tricked into interpreting the page as UTF-7. This can be used for a cross-site scripting attack as the < and > marks can be encoded as +ADw- and +AD4- in UTF-7, which most validators let through as simple text.

If needed for processing legacy data, UTF-7 can be enabled using the EnableUnsafeUTF7Encoding flag.

Microsoft.DotNet.PlatformAbstractions Package Deprecated

While technically not a breaking change, developers are strongly encouraged to stop using Microsoft.DotNet.PlatformAbstractions to detect information about the operating system. This library won’t be updated in the future and will become less accurate over time.

The following shows the deprecated methods and their replacements.

  • ApplicationEnvironment.ApplicationBasePath => AppContext.BaseDirectory
  • HashCodeCombiner => System.HashCode
  • RuntimeEnvironment.GetRuntimeIdentifier => RuntimeInformation.RuntimeIdentifier
  • RuntimeEnvironment.OperatingSystemPlatform => RuntimeInformation.IsOSPlatform(OSPlatform)
  • RuntimeEnvironment.RuntimeArchitecture => RuntimeInformation.ProcessArchitecture
  • RuntimeEnvironment.OperatingSystem => RuntimeInformation.OSDescription
  • RuntimeEnvironment.OperatingSystemVersion => RuntimeInformation.OSDescription and Environment.OSVersion

In part 2 of this series, we’ll look at the breaking changes that relate to some of .NET’s historical technologies.

Rate this Article

Adoption
Style

BT