.NET Framework 远程处理中的自动反序列化
依赖于运行时类型验证的远程处理系统必须反序列化一个远程流,然后才能开始使用它,未经授权的客户端可能会试图利用反序列化这一时机。为了免受这种攻击,.NET Framework 远程处理提供了两个自动反序列化级别:Low 和 Full。Low(默认值)防止反序列化攻击的方式是:在反序列化时,只处理与最基本的远程处理功能关联的类型,如自动反序列化远程处理基础结构类型、有限的系统实现类型集和基本的自定义类型集。Full 反序列化级别支持远程处理在所有情况下支持的所有自动反序列化类型。
警告
不要以为控制反序列化是应用程序要求的唯一安全机制。在分布式应用程序中,即使严格控制序列化也不能防止这种危险的发生:即未经授权的客户端截获通信内容,然后以某种方式利用该通信内容,即使只是向其他用户显示数据,也会造成损害。因此,虽然 Low 反序列化级别对某些基于自动反序列化的攻击类型提供了一定的保护,但仍然必须评估是否使用身份验证和加密方法来帮助保护您的数据。有关详细信息,请参见安全性。
下面的列表描述 .NET Framework 远程处理反序列化级别:
Low(默认级别)
.NET Framework 远程处理中的默认反序列化级别支持以下类型的反序列化:
远程处理基础结构对象。它们是在基本级别进行远程处理时所需的类型。
基元类型以及由基元类型构成的引用类型和值类型。
用 SerializableAttribute 属性标记但未实现 ISerializable 接口的引用类型和值类型。
实现 ISerializable 并且未发出序列化之外的其他任何要求的系统提供类型。
具有强名称并且位于未用 AllowPartiallyTrustedCallersAttribute 属性标记的程序集中的自定义类型。
实现 ISerializable 并且未发出序列化之外的其他任何要求的自定义类型。
实现 ILease 接口并且不属于 MarshalByRefObject 对象的类型。
用于激活(以支持客户端激活的对象)的 ObjRef 对象;也就是说,客户端可以反序列化返回的 ObjRef,但服务器却不能。
Full
.NET Framework 远程处理中的 Full 反序列化级别支持其他所有方案,包括以下附加类型的反序列化:
作为参数传递的 ObjRef 对象。
实现 ISponsor 接口的对象。
由 IContributeEnvoySink 接口在代理和客户端管道之间插入的对象。
作为参数传递的委托类型。
从作为参数传递的 MarshalByRefObject 继承的对象。
作为参数传递的 ISerializable 类型。
在 GAC 中存储并且未用 AllowPartiallyTrustedCallersAttribute 属性标记的类型。
如果应用程序要求使用仅在 Full 反序列化级别才可用的远程处理功能,您必须提供身份验证的类型和必要的加密级别,以保护任何在使用远程方案中的这些高级功能时可能遭受风险的资源。
您可以通过编程方式或使用应用程序配置文件设置反序列化级别。
以编程方式设置反序列化级别
要以编程方式设置反序列化级别,请在创建时将以下属性传递给 SoapServerFormatterSinkProvider 对象或 BinaryServerFormatterSinkProvider 对象。然后,当该值插入到接收链中时,远程处理系统将在格式化程序上设置该值。以下示例说明如何在宿主应用程序域中将反序列化级别设置为 Full。
// Creating a custom formatter for a TcpChannel sink chain.
BinaryServerFormatterSinkProvider provider = new BinaryServerFormatterSinkProvider();
provider.TypeFilterLevel = TypeFilterLevel.Full;
// Creating the IDictionary to set the port on the channel instance.
IDictionary props = new Hashtable();
props["port"] = 8085;
// Pass the properties for the port setting and the server provider in the server chain argument. (Client remains null here.)
TcpChannel chan = new TcpChannel(props, null, provider);
' Creating a custom formatter for your TcpChannel sink chain.
Dim provider As New BinaryServerFormatterSinkProvider()
provider.TypeFilterLevel = TypeFilterLevel.Full
' Creating the IDictionary to set the port on the channel instance.
Dim props As IDictionary = New Hashtable()
props("port") = 8085
' Pass the properties for the port setting and the server provider in the server chain argument. (Client remains null here.)
Dim chan As New TcpChannel(props, DBNull.Value, provider)
使用应用程序配置文件设置反序列化级别
要使用配置文件设置反序列化级别,必须显式指定 <formatter> 元素的 typeFilterLevel 属性。虽然这通常是在服务器端指定的,但您还必须为注册来侦听回调的客户端上的任何信道指定这一属性,以控制其反序列化级别。以下示例为应用程序域中的 SoapFormatter 和 BinaryFormatter 显式地将反序列化级别设置为 Low。
<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=Low />
<formatter ref="binary" typeFilterLevel=Low />
</serverProviders>
</channel>
</channels>
</application>
</system.runtime.remoting>
</configuration>
请参见
参考
RemotingConfiguration
BinaryServerFormatterSinkProvider.TypeFilterLevel
BinaryFormatter.FilterLevel