WPF 安全策略 — 平台安全性

Windows Presentation Foundation (WPF) 提供了各种安全服务,同时还综合利用了基础平台的各种安全功能,其中包括操作系统、CLR 和 Internet Explorer。 这些层联合为 WPF 提供了一种功能强大、防范深入的安全模型,以尝试避免任何单点故障,如下图所示:

WPF 安全性图示

本主题的其余部分讨论了与 WPF 密切相关的上述各层的功能。

本主题包括下列各节。

  • 操作系统安全性
  • 公共语言运行时安全性
  • Microsoft Internet Explorer 安全性
  • 相关主题

操作系统安全性

WPF 要求的最低等级的操作系统是 Windows XP SP2。 Windows XP SP2 的核心提供了多种安全功能,这些安全功能构成所有 Windows 应用程序的安全基础,其中包括用 WPF 构建的那些应用程序。 Windows Vista 合并了 WPF 的安全功能并将这些功能进一步延伸。 本主题广泛讨论了对于 WPF 来说特别重要的安全功能,并描述了 WPF 如何与这些安全功能集成以进一步提供深入防范功能。

Microsoft Windows XP Service Pack 2 (SP2)

除 Windows 的整体回顾和增强功能以外,Windows XP SP2 中还具备两个主要功能,本主题将对这两个主要功能进行讨论:

  • /GS 编译

  • Microsoft Windows Update.

/GS 编译

Windows XP SP2 通过重新编译多个核心系统库(其中包括所有 WPF 依赖项,如 CLR)以减轻缓冲区溢出,从而提供保护。 这是通过使用 /GS 参数以及 C/C++ 命令行编译器实现的。 虽然应显式避免缓冲区溢出,但是 /GS 编译还是提供了一个深入防范的示例,演示针对因缓冲区溢出而无意或蓄意创建的潜在漏洞。

一直以来,缓冲区溢出都会导致许多具有重大影响的安全问题。 当攻击者利用代码漏洞,注入超过缓冲区边界写入的恶意代码时,便会出现缓冲区溢出。 这样,攻击者便可改写函数的返回地址以执行其代码,从而截获执行代码的进程。 其结果是执行任意代码的恶意代码具有已截获进程的特权。

在更高的层次上,/GS 编译器标志通过注入特殊的安全 cookie 来保护具有本地字符串缓冲区的函数的返回地址,从而防止出现某些潜在的缓冲区溢出。 函数返回之后,安全 cookie 将与以前的值进行比较。 如果值发生变化,则可能发生缓冲区溢出,进程将报错并停止。 停止进程可以防止执行潜在的恶意代码。 有关更多详细信息,请参见 /GS(缓冲区安全检查)

WPF 是使用 /GS 标志进行编译的,这为 WPF 应用程序添加了另一个防护层。

Microsoft Windows Update 增强功能

Windows XP SP2 中还改进了 Microsoft Windows Update,以简化下载和安装更新的过程。 这些改进有助于确保 WPF 客户的系统(尤其是安全更新方面)是最新的,从而大大地提高了他们的安全性。

Windows Vista

Windows Vista 的 WPF 用户可从此操作系统的附加安全增强获益,包括“最少特权用户帐户”、代码完整性检查和特权隔离。

用户帐户控制 (UAC)

现在,Windows 用户需要管理员特权才能运行应用程序,因为许多应用程序的安装和(或)执行都要求其具有此特权。 例如,必须具有管理员特权才能向注册表中写入默认的应用程序设置。

使用管理员特权运行即意味着从授予了管理员特权的进程执行应用程序。 这样做的安全影响是:对于使用管理员特权运行的进程,截获了该进程的任何恶意代码都将自动继承这些特权,包括对关键系统资源的访问权限。

防范此安全威胁的一种方法是使用最少的必需特权来运行应用程序。 这称为最少特权原则,它是 Windows Vista 操作系统的核心功能。 此功能称为用户帐户控制 (UAC),由 Windows Vista UAC 使用,其使用方式主要包括下面两种:

  • 默认情况下,多数应用程序都使用 UAC 特权运行,即使用户是管理员也是如此;只有需要管理员特权的应用程序才需要使用管理员特权进行运行。 若要使用管理员特权运行,应用程序必须显式标记在其应用程序清单中,或作为安全策略中的一项进行显式标记。

  • 提供虚拟化等兼容性解决方案。 例如,许多应用程序都尝试写入受限制的位置,如 C:\Program Files。 对于在 UAC 下执行的应用程序,存在基于用户的备用位置,这些位置不要求使用管理员特权写入。 对于在 UAC 下运行的应用程序,UAC 虚拟化 C:\Program Files,从而使应用程序认为它们正在向该位置写入,实际上它们正在向基于用户的备用位置写入。 此兼容性做法使操作系统可以运行许多以前无法在 UAC 下运行的应用程序。

代码完整性检查

Windows Vista 集成了更深入的代码完整性检查,有助于防止在加载/运行时恶意代码注入到系统文件或内核。 这超出了系统文件保护的范围。

浏览器承载的应用程序的受限权限进程

浏览器承载的 WPF 应用程序在 Internet 区域沙盒内执行。 WPF 与 Microsoft Internet Explorer 的集成扩展了这种保护功能,并提供了其他支持。

适用于 XP 的 Internet Explorer 6 Service Pack 2 和 Internet Explorer 7

WPF 通过限制 XAML browser applications (XBAPs) 的进程特权综合利用操作系统安全性,以便进一步提供保护。 在启动浏览器承载的 WPF 应用程序之前,操作系统先创建一个用于删除进程令牌中不必要的特权的宿主进程。 被删除的特权包括关闭用户计算机、加载驱动程序以及对计算机上的所有文件进行读访问的能力。

适用于 Vista 的 Internet Explorer 7

在 Windows Internet Explorer 7 中,WPF 应用程序以受保护模式运行。 尤其是,XAML browser applications (XBAPs) 以中等完整性运行。

深入防范层

由于 XAML browser applications (XBAPs) 通常由 Internet 区域权限集设置在沙盒中,因此从兼容性的角度来看,删除这些特权并不会破坏 XAML browser applications (XBAPs)。 相反,还会创建一个额外的深入防范层;如果沙盒应用程序能够利用其他层并截获进程,则进程仍然只具备有限的特权。

请参见 Using a Least-Privileged User Account(使用最少特权用户帐户)。

公共语言运行时安全性

common language runtime (CLR) 提供了许多关键的安全性优点,包括确认和验证、Code Access Security (CAS) 以及安全关键方法。

确认和验证

为了提供程序集的隔离性和完整性,CLR 使用确认过程。 CLR 确认过程通过为指向程序集之外的地址确认其可移植可执行 (PE) 文件格式来保证程序集是隔离的。 CLR 确认过程还会确认程序集内嵌入的元数据的完整性。

为了确保类型安全性、防止出现常见的安全性问题(如 缓冲区溢出)以及通过子进程隔离启用沙盒,CLR 安全性使用了验证的概念。

托管应用程序被编译到 Microsoft 中间语言 (MSIL) 中。 当执行托管应用程序中的方法时,其 MSIL 将通过实时 (JIT) 编译编译到本机代码中。 JIT 编译包括一个应用了许多安全性和可靠性规则的验证过程,这些规则确保代码不会发生以下情况:

  • 违反类型协定

  • 引入缓冲区溢出

  • 随意访问内存。

不符合验证规则的托管代码不允许执行,除非它被视为可信代码。

可以对代码进行验证是 WPF 基于 .NET Framework 构建的一个主要原因。 就使用可验证代码来说,它大大降低了利用潜在漏洞的可能性。

代码访问安全性

客户端计算机公开托管应用程序可以访问的大量资源,包括文件系统、注册表、打印服务、用户界面、反射和环境变量等。 托管应用程序必须具有相应的 .NET Framework Code Access Security (CAS) 访问权限,然后才能访问客户端计算机上的任意资源。 CAS 权限是 CodeAccessPermission 的一个子类;CAS 对托管应用程序可以访问的每种资源都会实现一个子类。

CAS 在托管应用程序开始执行时向其授予的权限集合称为权限集,它由此应用程序提供的证据确定。 对于 WPF 应用程序,所提供的证据是启动这些应用程序的位置或区域。 CAS 确认了下列区域:

  • 我的电脑。 从客户端计算机启动的应用程序(完全受信任)。

  • 本地 Intranet。 从 intranet 启动的应用程序。 (部分受信任)。

  • Internet。 从 Internet 启动的应用程序。 (受信任度最低)。

  • 可信站点。 用户标识为受信任的应用程序。 (受信任度最低)。

  • 不可信站点。 用户标识为不可信任的应用程序。 (不可信任)。

对于以上各个区域,CAS 提供了一个预定义的权限集,其中包括与各个区域关联的信任级别匹配的权限。 这些元素包括:

  • FullTrust。 适用于从我的电脑区域启动的应用程序。 授予所有可能的权限。

  • LocalIntranet。 适用于从本地 Intranet 区域启动的应用程序。 授予权限子集,以提供对客户端计算机资源的适度访问权限,包括隔离存储区、无限制的 UI 访问、无限制的文件对话框、有限的反射以及对环境变量的有限访问。 未提供对注册表等关键资源的权限。

  • Internet。 适用于从 Internet可信站点区域启动的应用程序。 授予权限子集,以提供对客户端计算机资源的有限访问,包括隔离存储区、打开的文件(仅限于)以及有限的 UI。 实质上,此权限集使应用程序与客户端计算机隔离开来。

对于标识为来自不可信站点区域的应用程序,CAS不会授予任何权限。 因此,不存在与其对应的预定义的权限集。

下图演示了区域、权限集、权限和资源之间的关系。

CAS 权限集

Internet 区域安全沙盒的限制同样适用于 XBAP 从系统库导入的任意代码,包括 WPF。 这样可确保每个代码位都被锁定,即使是 WPF 也是如此。 遗憾的是,若要执行,XBAP 必须执行要求更多权限(相较于 Internet 区域安全沙盒启用的权限而言)的功能。

考虑包含下一页面的 XBAP 应用程序:

            Dim fp As New FileIOPermission(PermissionState.Unrestricted)
            fp.Assert()

            ' Perform operation that uses the assert

            ' Revert the assert when operation is completed
            CodeAccessPermission.RevertAssert()
FileIOPermission fp = new FileIOPermission(PermissionState.Unrestricted);
fp.Assert();

// Perform operation that uses the assert

// Revert the assert when operation is completed
CodeAccessPermission.RevertAssert();

若要执行此 XBAP,基础的 WPF 代码必须执行更多的功能(相较于可用于调用 XBAP 的功能而言),其中包括:

  • 创建窗口句柄 (hWnd) 以呈现

  • 调度消息

  • 加载 Tahoma 字体

从安全的角度讲,允许从沙盒中的应用程序直接访问任意这些操作会导致灾难性后果。

幸好 WPF 通过使用提升的特权代表沙盒中的应用程序来执行这些操作,从而解决了此问题。 对照 XBAP 的应用程序域的有限 Internet 区域安全权限检查所有 WPF 操作时,还将授予 WPF (与其他系统库类似)包含所有可能权限的权限集。

这要求 WPF 在接收提升的特权的同时,还应防止宿主应用程序域的 Internet 区域权限集对这些特权进行控制。

WPF 通过使用权限的 Assert 方法来实现这一点。 下面的代码演示这一过程。

            Dim fp As New FileIOPermission(PermissionState.Unrestricted)
            fp.Assert()

            ' Perform operation that uses the assert

            ' Revert the assert when operation is completed
            CodeAccessPermission.RevertAssert()
FileIOPermission fp = new FileIOPermission(PermissionState.Unrestricted);
fp.Assert();

// Perform operation that uses the assert

// Revert the assert when operation is completed
CodeAccessPermission.RevertAssert();

实质上 Assert 防止 WPF 所需的无限制的权限受到 XBAP 的 Internet 区域权限的限制。

从平台的角度讲,WPF 负责正确使用 AssertAssert 的错误使用会使恶意代码提升特权。 因此,应仅在需要的时候调用 Assert,并确保沙盒限制保持不变,这一点非常重要。 例如,不允许沙盒中的代码打开随机文件,但允许它使用字体。 WPF 允许沙盒中的应用程序通过调用 Assert 使用字体功能,并可以使 WPF 代表沙盒中的应用程序读取已知包含这些字体的文件。

ClickOnce 部署

ClickOnce 是一种全面的部署技术,它随 .NET Framework 提供并与 Microsoft Visual Studio 集成(有关详细信息,请参见 ClickOnce 部署概述)。 独立的 WPF 应用程序可以选择使用 ClickOnce 进行部署,而浏览器承载的应用程序必须使用 ClickOnce 进行部署。

使用 ClickOnce 部署的应用程序在Code Access Security (CAS) 基础上获得了一个附加安全层;实质上,ClickOnce 部署的应用程序会要求其所需的权限。 仅当这些权限不超过部署应用程序所在的区域的权限集时,才会授予其权限。 即使此权限集少于启动区域的权限集提供的权限,也会将其减少至所需的范围,从而将应用程序可以访问的资源数降至最低。 这样,如果应用程序被截获,对客户端计算机的潜在损坏的可能性则会降低。

安全关键方法

对于使用权限启用 XBAP 应用程序的 Internet 区域沙盒的 WPF 代码,必须持有最高等级的安全审核和控制。 为了便于此要求的实施,.NET Framework 针对提升特权的代码管理提供了新的支持。 具体来说,通过 CLR,您可以识别提升权限的代码,并使用 SecurityCriticalAttribute 进行标记;按照此方法,未使用 SecurityCriticalAttribute 进行标记的任何代码将变成透明的。 反之,未使用 SecurityCriticalAttribute 进行标记的托管代码则禁止提升特权。

安全关键方法允许将提升特权的 WPF 代码组织成安全关键内核,而剩下的代码则为透明的。 隔离安全关键代码使 WPF 工程团队可以对上述安全关键内核和标准安全实践以外的事务集中进行额外的安全分析和源控制(请参见 WPF 安全策略 — 安全工程)。

请注意,.NET Framework 允许受信任的代码扩展 XBAP Internet 区域沙盒,方法是允许开发人员写入标记有 AllowPartiallyTrustedCallersAttribute (APTCA) 并向用户的全局程序集缓存 (GAC) 部署的托管程序集。 使用 APTCA 标记程序集是一种高度敏感的安全操作,因为它允许任意代码调用此程序集,其中包括 Internet 上的恶意代码。 执行此操作时需要极为小心并采用最佳实践。用户必须选择信任该软件才能进行安装。

Microsoft Internet Explorer 安全性

除了减少安全问题和简化安全配置以外,Microsoft Internet Explorer 6 (SP2) 还包含几个安全增强功能,这些安全增强功能提高了 XAML browser applications (XBAPs) 用户的安全性。 扩展这些功能旨在使用户更好地对其浏览体验进行控制。

在 IE6 SP2 之前,用户可能会遇到下列问题:

  • 随机弹出窗口。

  • 混淆脚本重定向。

  • 网站上存在大量安全对话框。

在某些情况下,不可信的网站尝试通过假冒安装user interface (UI) 或反复显示 Microsoft ActiveX 安装对话框来欺骗用户,即使用户将其取消也是如此。 这些手段可能使大量用户受骗并做出错误决定,导致安装间谍应用程序。

IE6 SP2 包含若干可以缓解这些种类问题的功能,这些功能都以用户启动概念为中心。 IE6 SP2 检测用户在执行操作之前何时单击链接或页元素(称为用户启动),而对待它的方式与页面上的脚本在其他情况下触发类似操作时不同。 例如,IE6 SP2 集成一个弹出窗口阻止程序,用于在页创建弹出窗口之前检测用户单击按钮的情况。 这样,IE6 SP2 允许出现大多数无关紧要的弹出窗口,同时又可以防止出现用户未请求或不希望的弹出窗口。 被阻止的弹出窗口在新的信息栏下捕获,这样用户可以手动重写阻止并查看弹出窗口。

相同的用户启动逻辑也适用于打开/保存安全提示。 总是在信息栏下捕获 ActiveX 安装对话框,除非这些对话框表示从以前安装的控件进行升级。 这些措施一起为用户提供了一种更安全更容易控制的用户体验,保护他们不受某些网站的侵害,这些网站提示他们安装不想要的软件或恶意软件。

这些功能还保护了使用 IE6 SP2 浏览网站以下载和安装 WPF 应用程序的客户。 具体来说,这是因为 IE6 SP2 提供了更好的用户体验,其中降低了用户安装恶意或不正当应用程序的可能性,而不必考虑这些应用程序是利用什么技术(包括 WPF)生成的。 WPF 使用 ClickOnce 简化其应用程序经 Internet 下载的过程,从而加强了这些保护。 由于 XAML browser applications (XBAPs) 在 Internet 区域安全沙盒内执行,因此可以无缝启动。 此外,独立的 WPF 应用程序执行时还要求完全信任。 对于这些应用程序,ClickOnce 将在启动过程中显示一个安全对话框,提示应用程序正在使用额外的安全要求。 不过,这必须是用户启动的,将按照用户启动逻辑进行控制,并且可以取消。

Internet Explorer 7 合并和扩展了 IE6 SP2 的安全功能,作为持续安全承诺的一部分。

请参见

概念

代码访问安全性

安全性 (WPF)

WPF 部分信任安全

WPF 安全策略 — 安全工程

其他资源

Understanding Security in Microsoft Internet Explorer 6 in Windows XP SP2

Understanding and Working in Protected Mode Internet Explorer

Windows XP Service Pack 3

Windows Vista Security Guide