So, What's the Deal with SerializationException in Remoting & TypeFilterLevel?

Applications that used to work well in Framework 1.0 give System.Runtime.Serialization.SerializationException when run under Framework 1.1. The exception has this format:

System.Runtime.Serialization.SerializationException: Because of security restrictions, the type (type name) cannot be accessed. ---> System.Security.SecurityException: Request failed.

This issue is documened at https://www.gotdotnet.com/team/changeinfo/Backwards1.0to1.1/default.aspx\#00000153 (Secure Serialization in .NET Remoting - Backwards Breaking Changes from version 1.0 to 1.1)

A level of security has been added to Serialization. Specifically, there are now two levels of serialization security: Low (Default) and Full.

Low Level Security:

• Remoting infrastructure objects. These are the types needed to make remoting work at a basic level.
• Primitive types, and reference and value types that are composed of primitive types.
• Reference and value types that are marked with the SerializableAttribute attribute but do not implement the ISerializable interface.
• System-provided types that implement ISerializable with a reduced permission set.
• Custom types that implement ISerializable.
• Types that implement the ILease interface.
• ObjRef objects used for activation (to support client-activated objects).

Full Level Security:

• ObjRef objects passed as parameters.
• Objects that implement the ISponsor interface.
• Objects that are inserted between the proxy and client pipeline by the IContributeEnvoySink interface.

In version 1.1 of the .Net Framework, a new security feature was added to the .Net Remoting infrastructure called Type Filtering. This feature, which is enabled by default, limits the type of objects that may be marshaled by a Remoting client to a Remoting server. Type Filtering effectively prohibits the server from deserializing instances of CLR types that may serve as vectors of attack. This feature is part of Microsoft’s commitment to be secure by default.

The following outlines several of the threats that are mitigated by use of this feature (we are not going to give out details about how to exploit these threats), specifically when typeFilterLevel is set to Low:

Exposing a Remoting server with a method or member that takes a delegate.
Threat: Delegates may be used to invoke methods on other types that have the same signature

Exposing a Remoting server with a method or member that takes a MarshalByRefObject type.
Threat: The serialized form of a MarshalByRefObject contains a mutable URL

Exposing a Remoting server with a method or member that takes an ISerializable type.
Threat: Deserialization of an ISerializable type causes the Remoting infrastructure to run the type’s code.

Exposing a Remoting server with a method or member that takes an type found in the GAC on the server machine in an assembly without APTCA
Threat: Types in the GAC are well known to anyone with the .Net Framework installed.

Exposing a Remoting server that enables remote clients to register sponsors
Threat: There is no limit on the number of sponsors that can be registered.

You can set this functionality programmatically or using the config file:

Programmatic Solution:

IDictionary props = new Hashtable();
props["typeFilterLevel"] = "Full";
BinaryServerFormatterSinkProvider formatterProvider = new BinaryServerFormatterSinkProvider(props, null);

Here's the VB.NET code (just in case!)

If you are in VS 2003:

Dim h_Table As IDictionary
h_Table = New Hashtable()
h_Table("port") = 52000
Dim obj_FormatProvider As New BinaryServerFormatterSinkProvider()
obj_FormatProvider.TypeFilterLevel = Runtime.Serialization.Formatters.TypeFilterLevel.Full
Dim chnl As New TcpChannel(h_Table, Nothing, obj_FormatProvider)
ChannelServices.RegisterChannel(chnl)

If you are in VS 2002:

Dim h_Table As IDictionary

h_Table = New Hashtable()
h_Table("port") = 52000
Dim h_Table2 As IDictionary
h_Table2 = New Hashtable()
h_Table2("typeFilterLevel") = "Full"
Dim obj_FormatProvider2 As New BinaryServerFormatterSinkProvider(h_Table2, Nothing)
Dim chnl2 As New TcpChannel(h_Table, Nothing, obj_FormatProvider2)
ChannelServices.RegisterChannel(chnl2)

Config File Solution:

To use a configuration file to set the serialization level, you must explicitly specify the typeFilterLevel attribute of the <formatter> element. Although this is typically done on the server side, you must also specify this attribute to control the serialization level for any channel on the client registered to listen for a callback. The following example sets the serialization level to Full for both the SoapFormatter and BinaryFormatter in this application domain.

<configuration>
<system.runtime.remoting>
<application>
<service>
<wellknown
type="ServiceType, common"
objectUri=" ServiceType.soap"
mode="Singleton"
/>
</service>

<channels>
<channel ref="http">
<serverProviders>
<provider ref="wsdl" />
<formatter ref="soap" typeFilterLevel="Full" />
<formatter ref="binary" typeFilterLevel="Full" />
</serverProviders>
</channel>
</channels>
</application>
</configuration>

See https://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconautomaticdeserializationinnetremoting.asp for more info.

Your feedback is welcome.