.NET Framework 远程处理中的自动反序列化

本主题介绍一项传统技术,保留该技术是为了向后兼容现有的应用程序,不建议对新的开发使用该技术。现在应该使用  Windows Communication Foundation (WCF) 来开发分布式应用程序。

依赖于运行时类型验证的远程处理系统必须反序列化一个远程流,然后才能开始使用它,未经授权的客户端可能会试图利用反序列化这一时机。为了免受这种攻击,.NET Framework 远程处理提供了两种级别的自动反序列化:LowFullLow(默认值)防止反序列化攻击的方式是:只对与最基本的远程处理功能关联的类型进行反序列化,例如自动反序列化远程处理基础结构类型、有限的系统实现类型集和基本的自定义类型集。Full 反序列化级别支持对远程处理在各种情况下支持的所有类型进行自动反序列化。

5dxse167.Caution(zh-cn,VS.100).gif警告:
请不要认为控制反序列化是应用程序所需的唯一安全机制。在分布式应用程序中,即使是对序列化进行高度控制,仍无法防止未经授权的客户端截获通信,并以某种方式使用该通信(即使仅仅向其他用户显示数据)。因此,虽然 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 特性。虽然这通常是在服务器端指定的,但您还必须为注册来侦听回调的客户端上的任何信道指定这一特性,以控制其反序列化级别。下面的示例为应用程序域中的 SoapFormatterBinaryFormatter 显式地将反序列化级别设置为 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

概念

远程应用程序的配置