创建一个安全的平台
作者:Geir Olsen 来源:- 添加时间:2006-5-21 10:44:20在企业中实现Microsoft的三个安全方针,从而通过设计、缺省设置和部署来发布安全的应用程序。
by Geir Olsen
涉及技术:.NET Framework、.NET Security Policy
开发可以运行的应用程序、开发运行很快的应用程序、开发漂亮的应用程序——进而开发出安全的应用程序。如果这就是你的企业的应用程序开发方法,那么你并不是唯一这么做的企业。许多企业在开发软件解决方案时都遵循这个简单的方法。然而,我们现在所面临的安全威胁就意味着我们该做些改变了,.NET可能正是开发安全的应用程序的关键。我深信你必须在企业内部为安全性创建应对策略。这个策略包含多个方面,包括培训、技术选择、软件开发进程中的变化和你的运作计划的改变。
.NET Framework给开发人员和网络管理员提供了一整套新的安全工具,但是拥有这些工具并不意味着应用程序可以自动实现安全性。开发小组必须对这些新的安全性概念和如何实现这些概念有所了解,这样才能从这些工具中受益。我将通过Microsoft的Trustworthy Computing计划的一个后续计划来讲述其中的一些概念,这个计划为企业创建安全的平台提供了三个指导方针:通过设计确保安全、通过缺省设置确保安全和通过部署确保安全。如果你遵循这些方针,那么你受到攻击的可能性就会很小,而且如果安全性遭到破坏,你也可以更好的做准备来处理其后果。
你可能已经知道,.NET安全性是evidence based。如果你对.NET安全性概念不了解,那么就很难理解这个术语,而且这个术语也并不完全精确。在.NET中,当加载一个程序集(assembly)(一组部署,如DLL或EXE)时,它就被授予了一组权限。该权限定义了程序集中的代码可以运用哪些系统资源。该权限是在CLR(公共语言运行时)完成对程序集的授权评估后授予的。在授权评估期间,CLR查看收集在一起的evidence和配置策略来确定授予何种权限。因此,.NET不只是evidence based,它是policy based和evidence based。授予的权限是同.NET装载在一起的内置的权限,或为应用程序定制的权限。你在创建安全的平台时,了解策略是如何配置的、权限是如何基于该策略和这些runtime evidence授予的,这一点很重要(见图1)。如你所见,你可以创建开发小组必须使用的设计和架构方针。
图1. 创建.NET安全策略
设计时牢记安全性
你可以用.NET的新的安全特征为每个软件出版商或应用程序创建一个“sandbox”。一个sandbox包含可以得到的整套权限,网络管理员可以在任何必要的情况下授予这些权限。她可以创建一个策略,只授予确实需要的权限。这个概念比.NET之前的各种平台的安全性更强大,因为现在你可以根据软件编写者或软件下载来源来定义安全性了。然而,实现该功能并不容易,你在考虑实现该计划时,不要低估其复杂性。
我将从几个不同的角度来讲述其复杂性。如果你在经营一个软件开发公司,你就应该努力确保.NET的安全性。对于开发人员来说,这就意味着,你应该总是用程序集的安全需求来修饰程序集。如果一个程序集需要访问文件系统、Registry或环境变量,你就应该指定它们。.NET可以让你通过运用程序集级别的安全性代码属性来指定程序集的安全性。例如:[assembly:FileIOPermissionAttribute
(SecurityAction.RequestMinimum,
All="C:\\example\\sample.txt")]
在加载一个程序集时,CLR查看这些属性,并将这些需求看做是授权评估过程的一部分(见图2)。在这个例子中,该属性表明程序集至少有权限访问指定的文件。CLR将该需求与配置策略进行匹配,验证该策略授予的权限是否包括这个需求。如果授予了该权限,那么应用程序就会按期望运行;否则,程序集就不会加载,CLR会抛出一个异常。
图2. CLR授权
你可以指定RequestMinimum,就是说代码至少需要运行这个权限。你也可以指定RequestOptional,表明你希望运行这个权限,但没有也行。或者,你可以用RequestRefuse来表明“不要给我这个权限”。CLR运用RequestRefuse通过配置策略来限制授予的权限。
如果你的程序集表明它不需要文件I/O权限,那么CLR就不会授予它们这个权限,即使策略允许授予。你可以用.NET Framework装载的一个工具(permview.exe)来查看这些特殊的安全属性——当网络管理员配置安全策略时,该功能很有帮助。这些属性可以使我们进行更透明、更紧密的安全性管理(见图3)。
遗憾的是,.NET不需要开发人员添加这些属性,而且在创建程序集时,.NET也不会自动将这些属性添加到一个程序集的元数据中。虽然我们很想添加这些属性,但它们有很高的技术挑战性。然而,如果你添加了这些属性,每个.NET程序集就会拥有其安全性需求,正如它在元数据中拥有很多其它信息一样,如所有被包含的类型的定义和external dependencies。
图3. 查看一个程序集
在.NET Framework包含这种功能前,你必须将该步骤整合到开发进程和代码审核(code-review)过程中。如果你用安全性需求来修饰所有的程序集,那么你在创建管理授权的安全策略时就会得到很大的帮助,因为你现在就可以安全地授予所需的权限了。安全性容易受到攻击的原因是因为我们所运用的“无辜”的二进制代码,它们很可能受到侵袭,因为到目前为止,我们还没有.NET安全策略和安全属性机制来管理应该授予一个二进制代码哪些权限。
设置共用的安全性
如果你的企业没有开发自己的软件,但已经在部署用.NET技术开发的解决方案了,那么了解本文的内容同样也很重要。你应该了解什么样的策略可以用于安全性,然后创建部署方针来确保开发环境中的.NET安全性。
安全属性是.NET特征的一个例子,你可以在设计中运用它,从而实现“通过设计确保安全”。对程序集进行强命名和运用强命名(strong name)链接需求是其它的做法。常识告诉我们,在设计时建立安全性比在事后实现安全性成本要低。如果你建立的方针、模式或架构已经包含重要的安全组件了,那么你在一致性和重用方面就可以得到很多好处。然而,设计安全的应用程序只是创建一个安全的处理环境的一部分。下面,我将讲述拥有良好安全性的另一个方面:通过缺省设置来实现它。
10年前,我安装了第一个Sun OS,安装的缺省安全性包括一个super user(管理员),他不需要密码。这就使我可以从其它机子访问新机子的文件系统,而且还可以运用它的打印机监控程序,可以访问其它网络服务,而不会受到安全性的干预。但是Sun OS并不是具有这种问题的唯一的系统:SQL Server仍允许你安装产品,允许管理员帐号密码可以是空的。在Windows所有版本的报告中也有很多这种弱点,包括未受到保护的服务。
很多情况下,许多供应商提供的产品和服务并没有将大多数安全特征设置为缺省的。这么做的初衷就是,如果你需要安全性,你可以在安装产品后设置所需的安全性。供应商认为最终用户可以执行该功能。然而,由于文件丢失、不充分,或管理产品功能很难找到、丢失、不完整,所以设置安全性就很复杂。在Microsoft产品(如IIS和SQL Server)受到一系列攻击后,Microsoft意识到该做些改变了。因此,在Windows .NET Server 2003中,IIS不再是缺省安装的了,如果你要安装它,安装时就需要考虑安全性。
通过缺省设置转换到安全性
如果更多的产品具有可选功能,我们可以根据需求安装或不安装它们,同时实现最大限度的安全性,那么计算机行业就可以极大地受益了。供应商通常不考虑安全性,从而提高可用性;安全性和可用性通常是矛盾的,因为在完成同样的任务时,如果考虑安全性,就需要更多的步骤。然而,当整个网络因为安全性遭到破坏而瘫痪时,就没有哪个产品可以用了。你在考虑购买产品时,不仅需要考虑一时的可用性。
软件开发人员也会造成安全风险。他们通常具有domain user帐号,该帐号是其机器的本地管理员组的成员。这就是说,开发人员在运行他们的软件时,总是具有管理员特权。这会使工作进行得更快,但也会导致安全性弱点,因为在管理员帐号的安全环境中运行的软件很少面临安全性障碍。
为了克服这个问题,你需要配置你的开发人员的PC,使它们更像是你的最终用户的机器。Microsoft已经出版了一个白皮书,说明了如何实现这种配置。你也应该回顾一下你的安全策略,因为它为你做的所有安全决定提供了基础。在.NET Security Policy中,机子本地安装的所有代码在缺省情况下都具有Full Trust权限设置。该权限设置包括所有的标准权限和所有的定制权限。你不能修改Full Trust权限设置,但你可以通过配置将它与任何内置的设置或一个定制的权限设置进行交换。Full Trust权限设置在运行时,是不考虑安全性的。这就意味着,任何代码都可以运行,包括调用本地代码。为了改变这种情况,你可以将My_Computer_Zone代码组的PermissionSet从Full Trust改变到Nothing。在你的测试环境中保留该设置,并为你的每个软件解决方案定制一个策略。你可以通过.NET Framework Configuration Control Panel程序来改变.NET Security Policy。
开发人员在开发.NET解决方案时,应该总想着这些解决方案可以运行在一个安全的环境中。在这个环境中,所有的代码在缺省情况下都是安装在本地机器上的,没有权限。而且在这个环境中,所有安装的应用程序也必须确保它们具有良好的安全需求和定制的安全策略。我敢说,这种方法在开发和测试时会给开发人员带来麻烦,因为它需要我们改变一些坏的习惯,但我也敢说,它将会极大地提高安全性。让我们从一个小的实验项目开始,遵循这个方法来进行开发吧。IT经理应该通过改变缺省配置(如我在前面所述)来关闭Full Trust的大门,也应该要求软件出版商给他们提供符合该模式的软件解决方案。
在公司或企业中,建立一套安全方针或需求,并确保在企业的每个软件项目中实现它们。我在整篇文章中都讲述了开发人员和IT经理的职责,因为.NET安全性需要双方的努力。IT经理必须确保他们了解.NET安全策略,这样他们才能在所有机子上创建一个安全的.NET策略缺省配置。开发人员必须确保实现必要的属性,发布可以在安全的环境中部署的解决方案。
通过部署确保安全性
Microsoft声称,同以前的版本相比,Windows .NET Server 2003的attack surface要小很多。原因是缺省安装的服务少多了,而且我们也已经根据风险模式(threat model)对那些安装的服务进行了分析和安全审核。创建一个安全的系统架构的最重要的一个方面就是要全面了解你的部署环境和它可能呈现的潜在的安全漏洞。
在讲述软件架构和安全性、性能、可扩展性、有效性以及恢复性问题时,运用更新的、详细的部署图(deployment diagram)很有帮助。你的部署图是整个attack surface图的一个重要的部分。就像Microsoft已经定义了Windows .NET Server的attack surface一样,你必须了解你的软件和硬件系统的attack surface(见图4)。
图4. 正确部署
.NET提供了几个重要的特征,你可以运用它们使你的attack surface更小。你可以签署程序集来运用.NET的tamper-protection机制,你可以用强命名链接需求特征来确保只有你的代码可以调用你自己的程序集的公有接口。
下面我先讲述签署问题。当程序集加载时,你可以给CLR运用的你的.NET程序集添加一个签名,来确保程序集自创建以来没有被破坏。该签名可以是个强命名或是一个公开的证书(public certificate)。两者都是不能被改动的,强命名更容易实现,而证书具有更公开的可信性。如果你在开发内部使用的软件,或者你只是需要程序集不能被改动,那么就用强命名。
强命名是由程序集名称(name)、版本(version)和culture构成的。这些信息通过一个公钥(public key)和在程序集上创建的一个数字签名得到了“加强”。当加载程序集时,CLR验证该签名。如果程序集被改动了,那么它就不能加载。强命名并不对该故障完全负责,但它可以确保唯一性(uniqueness)和身份(identity)。基于证书的签名首先要从一个认证中心(certificate authority(CA))得到一个证书。在CA签发一个证书前,它会验证一个公司的身份,管理员就可以用证书中的信息来确保程序集的身份。从一个知名的CA得到证书就为你的产品提供了“信赖”。
由于这些安全特征提供的功能,一个侵犯者的程序集就不能替代你的部署环境中签名的程序集。如果你选用弱命名(weakly named)的程序集,或决定不签署你的程序集,那么侵犯者就可以用他的程序集替代你的程序集了。签署你的程序集会使部署中的attack surface更小。
强命名链接需求是你可以用来减小attack surface的另一个重要的特征。它假设你已经签署了你的程序集。你可以用一个强命名链接需求来修饰公有的类。你可以用一个公钥来指定链接需求。当受链接需求保护的一个类被实例化时,CLR就会查看调用者的程序集的签名是否有一个匹配的公钥。如果有,类就会被实时编译(Just In Time编译)并继续执行;如果没有,就会抛出一个异常,停止执行。这个新的.NET Framework安全特征可以确保你是你的程序集的唯一的调用者。
你在遵循这个实用的方法来保护部署中的系统时,也应该采用其它的方法来减小attack surface,如减少多余的技术,并为你用的产品创建标准的验证安装检核表(checklist)。一致性是很重要的,因为你用的技术越少,就越容易占有优势。.NET已经添加了一整套安全解决方案,这些方案在很多方面都是很新的,所以我们需要对它们进行学习和实践,从而充分利用。首先要掌握策略,然后再继续学习关于代码访问安全性的更多的细节。
关于作者:
Geir Olsen拥有学士学位和MCSD证书,他是Magenic Technologies的一位顾问,也是美国Minneapolis市的一位Gold Certified Microsoft Partner。他是位软件架构师,主要从事软件系统架构和软件开发过程的研究。他的联系方式是geiro@magenic.com。