silverlight:CLR 全面透彻解析Silverlight 2 中的安全性

CLR 全面透彻解析Silverlight 2 中<img src='/icons/98764de.gif' />安全性目录

  权限和不受信任代码沙箱处理

  透明模型

  CoreCLR 中透明度

  继承规则

  向 Silverlight 透明度公开

  在 2008 年 8 月MSDN 杂志“CLR 全面透彻解析”专栏中Andrew Pardoe 简要介绍说明了 CoreCLR 安全模型他介绍了为什么我们选择不使用 Silverlight 中代码访问安全性 (CAS) 策略还介绍了透明代码、SafeCritical 代码和关键代码的间区别在本期内容中我将详细介绍透明模型是如何生成、它在 Silverlight 中工作原理以及预期会在未来版本中实现哪些功能

  权限和不受信任代码沙箱处理

  在深入探讨透明模型的前先来了解在完整 Microsoft .NET Framework 中有关 CLR 安全性些背景知识对您会大有裨益CLR 提供了些机制可根据代码中显示代码运行位置、代码签名(如果存在)等证据来确定代码具有功能或权利(由权限表示)这可确保来自不受信任位置(如 Internet)代码不具有来自受信任位置(如本地计算机 Program Files 文件夹)代码所具有权限

  CLR 在其自己应用域中运行各个托管应用从不受信任位置安全运行代码首选机制是在经过沙箱处理应用域中运行它在这些域中运行代码被限定为只具有沙箱权限在这里沙箱是指和部分受信任代码相对应具有有限权限环境通常经过沙箱处理应用域会将代码分为两组即完全信任和部分信任在本节后面部分我将详细介绍这两个组用途以及如何区分它们

  为使这种分离更易于实现和使用我们在 .NET Framework 2.0 中引入了简单沙箱处理 API它们将为其沙箱创建具有给定权限集各个应用还将创建完全受信任列表(这些集并不在“全局集缓存Cache”(GAC) 中 GAC 中所有集都已完全受信任)已加载到此应用域中但不在完全信任集列表中任何内容都将获得沙箱授予权限集如果是从 Internet 运行应用则这将是内置 Internet 权限集Shawn Farkas 是 CLR 安全团队(Team)中名软件Software设计工程师他在博客中对有关如何使用此 API 做了精彩介绍网址为 go.microsoft.com/fwlink/?LinkId=124952

  利用此模型主机(例如浏览器插件)将为在其下运行每个应用都创建个应用这些将作为部分受信任内容被加载并获得沙箱权限集主机可能还希望(安全地)封装些完全信任托管或本机并以库形式将它们提供给托管应用这些库集将位于完全信任集列表中例如文件系统访问是种特权操作但将信息保存在本地非常有用并且如果处理正确(位置固定、从不执行等)它也可以非常安全但如果真正公开此功能还是会面临很大挑战

  透明模型

  实际上透明模型对 CoreCLR(Silverlight 版本 CLR)而言并非新事物自从 .NET Framework 2.0 推出以来它就直存在最初引入它是为了解决将服务公开给部分受信任代码框架库数量不断增加问题以及它们在 .NET Framework 团队(Team)内引发内部安全审计问题具有 AllowPartiallyTrustedCallers (APTCA) 属性库会向部分受信任代码公开完全信任服务在这里部分受信任代码是指需要对 APTCA 库进行适当安全检查具有潜在危险些内容

  在引入透明度的前整个 APTCA 集都要进行代码审计这要付出极其昂贵代价尤其是考虑到许多库可能是在常见特权而它们在其他情况下却是完全安全

  我们开发透明度是为了在特权代码和非特权代码的间创建个强大隔离边界在此模型中有两类代码即透明代码和关键代码透明代码有以下限制:

  不能声明权限或进行提升

  不能包含不安全或不可验证代码这被视为种关键操作如果它们出现在透明代码中则会导致各要求被注入

  不能直接关键代码本章稍后会对例外情况加以介绍说明

  不能本机代码或具有 SuppressUnmanagedCodeSecurity 属性 API

  无法满足 LinkDemands所有 LinkDemands 都将成为完整堆栈遍历要求

  所有权限要求都流过透明代码且和应用域相悖;透明代码无法声明这些要求因此透明代码始终被限制为具有沙箱权限关键代码没有这种限制它可以执行上述操作因此 APTCA 安全审计负担被减少到只有关键区域

  那么两种类型代码是如何交互?如果开发人员认为关键 API 可以安全地从透明代码进行(例如操作系统来检索日期和时间 API)则他可以将其标记为 TreatAsSafe(代码中实际属性:SecurityTreatAsSafe)来实现这另外需要注意重要点是在 2.0 透明模型中透明度规则仅限于因此公共 Criticals 就是暗指 TreatAsSafe(在本专栏通篇我都将此透明模型称为 2.0 透明模型实际上此透明模型也是 .NET Framework 3.0、3.5 和 3.5 SP1 版本部分)因此公共 Critical 思路方法可通过透明代码

  2.0 透明模型在 .NET Framework 后续桌面版本中作用非常大它使安全性更易于推理得出还可以使团队(Team)能够更方便地向部分信任应用公开其服务借助 CoreCLR我们不但可以改进透明系统而且还可以使其成为在整个运行时强制保证安全并基于它构建代码主要机制

  CoreCLR 中透明度

  虽然透明度在访问安全性方面很有帮助但它并不是 .NET Framework 中有关安全性决定原因区别应用区别沙箱可能具有区别权限集从 Internet 运行应用和从企业 Intranet 运行应用具有区别权限因此必须在代码中检查并声明这些权限

  我们知道所有基于 CoreCLR 构建丰富 Internet 应用都是在 Web 浏览器内运行因此使用 CoreCLR 我们可以做出些简单假设个假设是每个应用域都有个固定沙箱我们不必处理各个单独权限我们已经知道了各个 Silverlight 应用将具有哪些权限只有两个权限集即完全信任和 Silverlight 沙箱我们做出第 2个假设是所有 Silverlight 应用都是部分受信任因此其权限不能提升到超过 Silverlight 沙箱权限

  这些都属于很重要简化处理它们可以产生以下结果:所有 Silverlight 应用都是透明并接收 Silverlight 沙箱权限集Silverlight 平台库(其中大部分是完全信任)将仅由 Silverlight 应用因此我们不必要求特定权限;将危险 API 标记为 Critical 就足够了最后由于没有任何要求所以我们永远也不需要停止权限堆栈遍历并且也不需要声明

  这样透明度成为 CoreCLR 中安全执行机制我们可以忽略大部分 CAS为使其成为更强大执行机制我们加强了透明代码规则并对透明系统做了更多改进使其更加直观和有效

  您可能已经注意到对于 2.0 透明模型在透明代码中执行不安全或不可验证代码会导致注入 UnmanagedCodePermission 要求而不是立刻导致故障/异常通常此权限只应在完全信任情况下可用所以此代码在部分信任情况下将失败但在其他情况下均有效

  但是对于 CoreCLR我们并没有引入权限要求概念因此在发生这种情况时将引发异常(而不是在新透明模型中注入要求)虽然此类型代码在两个模型中均会失败但现在其性能却提高了在最终失败的前我们不必处理要求堆栈遍历

  而且在 Silverlight 中所有代码默认都是透明这包括 Silverlight 平台库;所有关键代码都必须显式批注这为我们提供了个安全默认设置可减少意外创建隐式 Critical 思路方法可能此外还添加了许多有关类型继承和思路方法覆盖规则对此我将在“继承规则”部分加以解释

  我的前曾提到过标有 TreatAsSafe 关键 API 被视为可从透明代码我还指出由于桌面框架上透明度仅适用于因此公共关键 API 就是暗指 TreatAsSafe在 CoreCLR 中我们创建了个新属性 SafeCritical(再次重申实际批注是 SecuritySafeCritical)用来描述既被视为关键代码又可以从透明代码代码现在透明度不但在集内部应用而且还跨集应用因此关键代码(无论是否为公共)将无法从透明代码

  这改变有助于消除对如何向透明代码公开关键代码所产生混淆首先所有关键代码都受限制公共代码也不例外因此添加关键批注始终都意味着透明代码无法对其进行而且只有当 Critical 属性已经存在时TreatAsSafe 才有意义(要求两个属性可能会导致混淆可以将 TreatAsSafe 放在 Transparent 思路方法上即使它并不执行任何操作)最后由于只有种思路方法指定安全代码因此关键代码可进步简化模型

  对这新属性需要了解件事就是当我们谈论关键代码时通常也包括了 SafeCritical 代码这是 SafeCritical 代码是关键代码它具有和关键代码同样功能此外它还可以由透明代码因此为使其真正成为安全关键代码库开发人员必须确保在关键代码(不是安全代码)的前进行相应输入验证或其他安全检查并确保在的后进行必要输出验证和副作用检查在这里 SafeCritical 变成了项约定它声明此思路方法访问是关键代码但要在访问的前和的后进行所有相应检查在新透明模型中安全审计焦点是 SafeCritical 代码

  继承规则

  为使透明模型有效我们还必须确保类型或思路方法闭包也是安全在派生类型或思路方法时如果使用资源访问权限区别于基类型或基类思路方法权限则会引发些访问保护问题尤其是在转换为更具访问性父类型或接口时例如假设某人想创建透明虚拟思路方法个关键覆盖思路方法(如 )然后又想通过转换为 Object. 来防止透明代码该覆盖思路方法

  您可以假设对透明级别存在个访问和功能层级因此当您从透明代码依次转换为 SafeCritical 代码和关键代码时访问将会更受限制和/或功能得到不断增强(在这里访问是指包含以及此级别代码能力)类型继承规则是指派生类型受限程度必须至少和基类型这可防止开发人员意外创建透明代码所关键类型重载图 1 显示了此模式所允许内容

CLR 全面透彻解析Silverlight 2 中<img src='/icons/98764de.gif' />安全性图 1 允许类型继承模式

基类型 允许派生类型
透明 透明、SafeCritical 或关键
SafeCritical SafeCritical、关键
关键 关键



  虚拟思路方法覆盖规则有所区别 — 派生思路方法必须具有和基类思路方法相同透明代码可访问性图 2 显示了此模式所允许内容

CLR 全面透彻解析Silverlight 2 中<img src='/icons/98764de.gif' />安全性图 2 允许思路方法继承模式

基类(虚拟/接口)思路方法 允许覆盖思路方法
透明 透明、SafeCritical
SafeCritical 透明、SafeCritical
关键 关键



  请注意我们不允许透明虚拟思路方法关键覆盖这样时很容易地就可以转换为基类思路方法并绕过对覆盖关键检查我们允许透明 SafeCritical 覆盖这种转换不会导致任何后果 — 无论怎样透明代码都可以访问 SafeCritical 代码我们还允许 SafeCritical 虚拟思路方法透明覆盖乍看起来这似乎有些令人惊讶但这实际上是安全这种转换同样不会导致任何危险后果

  总而言的对于 Silverlight 透明模型请记住默认情况下所有代码都是透明所有 Silverlight 应用也是完全透明所有指示其他内容标记将被忽略此外固定权限集表示透明度是 CoreCLR 所需执行机制图 3 整理总结了这 3种类型代码及其功能和特点

CLR 全面透彻解析Silverlight 2 中<img src='/icons/98764de.gif' />安全性图 3 比较透明代码、SafeCritical 代码和关键代码

透明 SafeCritical 关键
访问限制 不能直接关键代码 可以实现关键代码所有功能 必须确保在关键代码的前和的后执行相应检查 有权限且有能力任何代码仅等效于完全信任 永远不能由透明代码直接但可以通过 SafeCritical 代码公开
不安全代码 不能包含不安全或不可验证代码 可以包含不安全或不可验证代码 可以包含不安全或不可验证代码
可用于应用或平台代码 在应用和平台代码中均存在 仅对 Silverlight 平台集可用 仅对 Silverlight 平台集可用
类型继承特征 类型必须从其他透明类型派生 类型必须从透明或 SafeCritical 类型派生 类型可以从所有类型派生(和批注无关)
思路方法覆盖特征 思路方法必须覆盖透明或 SafeCritical 虚拟/接口思路方法 思路方法必须从透明或 SafeCritical 虚拟/接口思路方法派生 思路方法必须从关键虚拟/接口思路方法派生



  向 Silverlight 透明度公开

  Silverlight 透明模型许多优势都表现在简化 Silverlight 平台安全执行方面由于 Silverlight 是个封闭式平台因此目前没有受信任第 3方库概念因而开发人员和 Silverlight 透明模型交互仅限于允许其 API(透明或 SafeCritical)应用是完全透明但是对于 .NET Framework 平台它并不是封闭因此可以开发附加库以使安全执行更为简单

  开发人员或许能够在下个主要版本桌面框架中看到这些改进我们在 .NET Framework 2.0 中引用透明模型使分析和判断 APTCA 库安全性变得更加简单;Silverlight 透明模型在这方面又向前迈进了它使我们能够做出些假设和保证而这些在以前必须要通过仔细审查得到确认在未来我们计划在 .NET Framework 中全面引入围绕透明代码严格规则、SafeCritical 属性以及透明继承规则我们还计划将其提供给外部开发人员

  桌面框架和 Silverlight 的间个主要区别在于桌面框架上大多数应用是针对完全信任环境构建而所有 Silverlight 应用都是针对部分信任环境构建大部分桌面应用可以根据需要执行任何操作而且可以继续这样做完全不必考虑透明问题在实现过程中它们将被视为关键应用

  APTCA 库开发人员将会体验到我们 Silverlight 平台许多优势APTCA 库可审核方面现在侧重于 SafeCritical 层关键层无法从部分受信任透明代码进行访问而且继承规则引入可确保库覆盖和派生不会在无意间暴露任何安全漏洞(但请记住由于桌面框架中存在各种可能沙箱因此 APTCA 库必须分别处理各个权限这使得 SafeCritical API 可能必须执行权限要求以及其他输入验证检查)

  更为严格透明代码规则还意味着部分受信任应用将比以往更加安全、性能更强在 .NET Framework 2.0 透明模型中或包含不安全或不可验证代码透明代码要面对被注入 UnmanagedCodePermission 要求还要在不安全/不可验证代码时面对代价高昂堆栈遍历这通常会导致故障大部分沙箱权限授予集中都不包含此权限

  在新透明模型中这些被视为硬故障在 CoreCLR 中没有注入要求因而也没有堆栈遍历通过将新透明模型引入下版本桌面框架我们希望使开发 APTCA 库工作变得更加轻松并改善在开发部分受信任应用体验

  请将您想询问问题和提出意见发送至 [email protected]

  Andrew Dai 是 Microsoft CLR 团队(Team)名项目经理(project manager)他负责 Silverlight 和桌面框架安全性问题

Tags:  silverlight2 silverlight.2.0 silverlight是什么 silverlight

延伸阅读

最新评论

发表评论