[Remoting]dotNet Framework升级后Remoting信道使用的安全问题

简介:

[Remoting]dotNet Framework升级后Remoting信道使用的安全问题

 

编写者:郑昀@UltraPower

dotNet  Framwork 1.1

关键字:Channel,remoting

编写时间:2005-5-18

 

摘要:.NET Framework升级之后,Remoting中的事件就需要对信道进行特别的设置,要自己创建BinaryServerFormatterSinkProvider类的实例,并且将其TypeFilterLevel设为TypeFilterLevel.Full,这是.NET 1.1中增强了安全设置后必须要做的事情。

 

引子:

现在使用以前在dotNET Framework1.0下编写的例子代码时,Remoting常常会在使用Channel时发生异常,错误如下所示:

中文错误报告以及错误堆栈

System.Security.SecurityException: 不允许类型 System.DelegateSerializationHolder和从中派生的类型(例如 System.DelegateSerializationHolder)在此安全级别上被反序列化。

Server stack trace:

   at System.Runtime.Serialization.FormatterServices.CheckTypeSecurity(Type t, TypeFilterLevel securityLevel)

   at System.Runtime.Serialization.Formatters.Soap.ObjectReader.CheckSecurity(ParseRecord pr)

英文错误报告

[SecurityException: Type System.DelegateSerializationHolder and the types derived from it (such as System.DelegateSerializationHolder) are not permitted to be deserialized at this security level.]

这个错误是因为.NET Framework升级到1.1后,加强了安全设置导致的。

 

错误重现:

我是在下载并编译使用以前MSDN旧版本的RemSSPI.Exe代码(该文章在http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/remsspi.asp,是讲解如何穿越Remoting边界提供安全认证的。它已经更新了,RemSSPI.exe例子已经纠正了这个错误)时,遇到这个错误的。

异常发生在

REMSSPI\Microsoft\Samples\Security\SSPI\Sample\ControlPanel\Client

MainForm.cs下面这句话上:

_ClientSecurity.SignedMessageEvent =

                newMicrosoft.Samples.Security.SSPI.Sample.ClassLibrary.Client.SignedMessageDelegate(this.SignedMessage);

 _ClientSecurity对象是这么创建的:

_ClientSecurity = (Microsoft.Samples.Security.SSPI.Sample.ClassLibrary.Client.Security)Activator.GetObject(typeof(Microsoft.Samples.Security.SSPI.Sample.ClassLibrary.Client.Security), clientURL);

 这时候,他所使用的信道创建方法如下所示:

ChannelServices.RegisterChannel(newHttpChannel(Convert.ToInt32(txtClientPort.Text)));

 只有将其改为:

//////////////////////////////////////////////////////////
/// zhengyun 20050518

BinaryServerFormatterSinkProvider serverProv = newBinaryServerFormatterSinkProvider();

serverProv.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;

BinaryClientFormatterSinkProvider clientProv = newBinaryClientFormatterSinkProvider();

IDictionary props = new Hashtable();

props["port"] = Convert.ToInt32(txtClientPort.Text);

HttpChannel chan = new HttpChannel(props, clientProv, serverProv);

///
//////////////////////////////////////////////////////////

 

//
// Setup the channel for the client side object
//
ChannelServices.RegisterChannel(chan);

方可。

 

另外一个例子也可以重现本错误:http://download.microsoft.com/download/MSPressPub/6172/1.0/W98NT42KMeXP/EN-US/Remoting.exe

 

原因:

RemotingFAQ 中讲到:

当你使用客户端激活的对象、事件或者委托时,在.NET Framework 1.1下你会遇到以下两种错误:

·       System.Security.SecurityException
Type System.DelegateSerializationHolder and the types derived from it (such as System.DelegateSerializationHolder) are not permitted to be deserialized at this security level.

·       System.Runtime.Serialization.SerializationException
Because of security restrictions, the type System.Runtime.Remoting.ObjRef cannot be accessed.

 要想回到以前的默认模式,就是允许跨越Remoting边界传递委托和对象引用,你必须改变“typeFilterLevel”。

 

微软的正式解释:

gotdotnet也正式谈到了这个问题,Secure Serialization in .NET Remoting你也可以在这里找到这文档的中文翻译::

这一问题影响到的APIs有:

System.Runtime.Serialization.ISerializable 
System.Runtime.Remoting.ObjRef 
System.Runtime.Remoting.Lifetime.ILease 
System.Runtime.Remoting.Lifetime.ISponsor 
System.Runtime.Remoting.Contexts.IContributeEnvoySink 
System.Runtime.Remoting.Channels.SoapServerFormatterSinkProvider 
System.Runtime.Remoting.Channels.BinaryServerFormatterSinkProvider

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

警告   不要以为控制反序列化是应用程序需要的唯一安全机制。在分布式应用程序中,即使严格控制序列化也不能防止这种危险的发生:即未经授权的客户端截获通信内容,然后以某种方式利用该通信内容,即使只是向其他用户显示数据,也会造成损害。因此,虽然 Low 反序列化级别对某些基于自动反序列化的攻击类型提供了一定的保护,但您仍然必须考虑是否使用身份验证和加密来为您的数据提供完全的保护。有关详细信息,请参见安全性

·         如果应用程序需要使用仅在 Full 反序列化级别才可用的远程处理功能,您必须提供身份验证的类型和必要的加密级别,以保护任何在使用远程方案中的这些高级功能时可能遭受风险的资源。

解决之道:

您可以通过编程方式或使用应用程序配置文件设置反序列化级别。

以编程方式设置反序列化级别

若要以编程方式设置反序列化级别,请在创建时将以下属性传递给 SoapServerFormatterSinkProvider 对象或BinaryServerFormatterSinkProvider 对象。然后,当该值插入到接收链中时,远程处理系统将在格式化程序上设置该值。以下示例说明如何在宿主应用程序域中将反序列化级别设置为 Full

[C#]

// 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);

[Visual Basic]

' 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.

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.)

Dim chan As New TcpChannel(props, null, 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>

</configuration>

更多信息:

BinaryServerFormatterSinkProvider 

为使用 BinaryFormatter 的服务器格式化程序信道接收器提供程序提供实现。

 

备注

信道接收器通过 IServerChannelSinkProvider 接口的实现连接到服务器信道。所有远程处理服务器信道均提供以IServerChannelSinkProvider 为参数的构造函数。

 

信道接收器提供程序存储在一个链中,在向信道构造函数传递外部信道接收器提供程序之前,用户负责将所有的信道接收器提供程序链接在一起。为此,IServerChannelSinkProvider 提供了名为 Next 的属性。当在一个配置文件中提供了多个信道接收器提供程序时,远程处理结构将这些程序按在配置文件中找到的顺序链接起来。在RemotingConfiguration.Configure 调用过程中创建信道时,将创建信道接收器提供程序。

 

格式化程序接收器在运行时使用接收器配置属性来配置信道。接收器属性可在配置文件中指定,或在 IDictionary 中以编程方式指定。在配置文件中,所有值都由字符串表示,但是当以编程方式生成属性 IDictionary 时,值类型可以用它们的本机值或字符串指定。

 

BinaryServerFormatterSinkProvider.TypeFilterLevel 属性

注意:此命名空间、类或成员仅在 .NET Framework 1.1 版中受支持。

获取或设置 BinaryServerFormatterSink 所执行的自动反序列化的 TypeFilterLevel

 

.NET Framework 安全性: 

对直接调用方完全信任。部分受信任的代码不能使用此成员。有关更多信息,请参阅在部分受信任的代码中使用库

 

 

编写者:郑昀@UltraPower

目录
相关文章
ASP.NET Core微服务之基于MassTransit实现数据最终一致性(1)
Tip: 此篇已加入.NET Core微服务基础系列文章索引 一、预备知识:数据一致性   关于数据一致性的文章,园子里已经有很多了,如果你还不了解,那么可以通过以下的几篇文章去快速地了解了解,有个感性认识即可。
1477 0
ASP.NET Core微服务之基于MassTransit实现数据最终一致性(2)
Tip: 此篇已加入.NET Core微服务基础系列文章索引 一、案例结构与说明   在上一篇中,我们了解了MassTransit这个开源组件的基本用法,这一篇我们结合一个小案例来了解在ASP.NET Core中如何借助MassTransit+Quartz.Net来实现数据的最终一致性。
1368 0
|
Web App开发 XML 网络协议
艾伟:Remoting和Webservice的区别
本系列文章导航 创建一个示例和WebMethod特性解析 WebService特性和数组类型解析 类和结构体解析 利用YAHOO公开API做天气预报Web服务 Webservice 的设计和模式 Remoting和Webservice的区别 其实现的原理并没有本质的区别,在应用开发层面...
1042 0
|
Web App开发 安全 .NET
艾伟_转载:WCF、Net remoting、Web service概念及区别
  Windows通信基础(Windows Communication Foundation,WCF)是基于Windows平台下开发和部署服务的软件开发包(Software Development Kit,SDK)。
1124 0
|
网络安全 Windows 数据库
.Net Remoting的双向通信和Windows Service的宿主服务
原文:.Net Remoting的双向通信和Windows Service的宿主服务      作为微软分布式技术之一的.Net Remoting,从性能、安全等各方面来说都是相对比较稳定的,也是一项比较成熟的分布式技术。
896 0
|
Java .NET Apache
(11)学习笔记 ) ASP.NET CORE微服务 Micro-Service ---- Thrift高效通讯 (完结)
一、 什么是 RPC Restful 采用 Http 进行通讯,优点是开放、标准、简单、兼容性升级容易; 缺点是性能略低。在 QPS 高或者对响应时间要求苛刻的服务上,可以用 RPC(Remote Procedure Call),RPC 由于采用二进制传输、TCP 通讯,所以通常性能更好。
3984 0
|
C# 网络协议
.Net中Remoting通信机制简单实例
原文:.Net中Remoting通信机制简单实例 .Net中Remoting通信机制 前言: 本程序例子实现一个简单的Remoting通信案例     本程序采用语言:c#   编译工具:vs2013工程文件   编译环境:.
812 0
|
网络协议 网络架构
.Net中Remoting通信机制
原文:.Net中Remoting通信机制 Remoting通信机制 Remoting介绍 主要元素 通道类型 激活方式 对象定义 Remoting介绍 什么是Remoting,简而言之,我们可以将其看作是一种分布式处理方式。
831 0