Knowing that the support for .NET 6 will end soon (I’m writing this post August 2024, support ends in November 2024), I’m helping my customers move to .NET 8.
UPDATE: After writing this article, Microsoft created a blog post with more details about the removal of the Binary Formatter in .NET 9.
Although Microsoft does a lot of effort to guarantee backwards compatibility, we still encountered some problems. In one (older) application where we were using (Fluent)NHibernate, we got the following error after upgrading:
FluentNHibernate.Cfg.FluentConfigurationException: An invalid or incomplete configuration was used while creating a SessionFactory. Check PotentialReasons collection, and InnerException for more detail.
---> System.NotSupportedException: BinaryFormatter serialization and deserialization are disabled within this application. See https://aka.ms/binaryformatter for more information.
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph)
at FluentNHibernate.Utils.Extensions.DeepClone[T](T obj)
at FluentNHibernate.Mapping.SubclassMap`1.FluentNHibernate.Mapping.Providers.IIndeterminateSubclassMappingProvider.GetSubclassMapping(SubclassType type)
at FluentNHibernate.Visitors.SeparateSubclassVisitor.ProcessClass(ClassMapping mapping)
at FluentNHibernate.MappingModel.ClassBased.ClassMapping.AcceptVisitor(IMappingModelVisitor visitor)
at FluentNHibernate.Visitors.DefaultMappingModelVisitor.Visit(ClassMapping classMapping)
at FluentNHibernate.MappingModel.HibernateMapping.AcceptVisitor(IMappingModelVisitor visitor)
at FluentNHibernate.Visitors.DefaultMappingModelVisitor.<Visit>b__10_0(HibernateMapping x)
at FluentNHibernate.Utils.CollectionExtensions.Each[T](IEnumerable`1 enumerable, Action`1 each)
at FluentNHibernate.Visitors.DefaultMappingModelVisitor.Visit(IEnumerable`1 mappings)
at FluentNHibernate.PersistenceModel.ApplyVisitors(IEnumerable`1 mappings)
at FluentNHibernate.PersistenceModel.BuildMappings()
at FluentNHibernate.PersistenceModel.EnsureMappingsBuilt()
at FluentNHibernate.PersistenceModel.Configure(Configuration cfg)
at FluentNHibernate.Cfg.MappingConfiguration.Apply(Configuration cfg)
at FluentNHibernate.Cfg.FluentConfiguration.BuildConfiguration()
--- End of inner exception stack trace ---
at FluentNHibernate.Cfg.FluentConfiguration.BuildConfiguration()
at FluentNHibernate.Cfg.FluentConfiguration.BuildSessionFactory()
This error happens for a good reason as usage of the BinaryFormatter is considered dangerous as it is a possible attack vector due to deserialization vulnerabilities.
From the documentation:
Deserialization vulnerabilities are a threat category where request payloads are processed insecurely. An attacker who successfully leverages these vulnerabilities against an app can cause denial of service (DoS), information disclosure, or remote code execution inside the target app.
In .NET, the biggest risk target is apps that use the BinaryFormatter type to deserialize data. BinaryFormatter
is widely used throughout the .NET ecosystem because of its power and its ease of use. However, this same power gives attackers the ability to influence control flow within the target app. Successful attacks can result in the attacker being able to run code within the context of the target process.
If you don’t want to replace the BinaryFormatter, in .NET 8 you can still allow BinaryFormatter usage by setting the following flag:
However be aware that in .NET 9, this flag is ignored and the BinaryFormatter implementation always throws exceptions on use.
So the way forward is clear, replace the BinaryFormatter by an alternative(more about this below). However if you are really stubborn and want to keep using the BinaryFormatter, you can switch to the unsupported(!) compatibility package:
Replacing the BinaryFormatter
So the recommended way is to replace the BinaryFormatter. To help you, the .NET team recommends any of the following options depending on your needs:
- Migrate to System.Text.Json (JSON)
- Migrate to DataContractSerializer (XML)
- Migrate to MessagePack (binary)
- Migrate to protobuf-net (binary)
Important to notice is that none of these option are an in-place replacement for the BinaryFormatter, so development work and thorough testing will be needed to avoid introducing bugs.
Here is an overview that compares the different options:
Good lucking replacing the BinaryFormatter!