WPF 安全策略 - 平台安全性

虽然 Windows Presentation Foundation(WPF)提供了各种安全服务,但它还利用基础平台(包括作系统、CLR 和 Internet Explorer)的安全功能。 这些层组合为 WPF 提供了一个强大的深度防御安全模型,该模型试图避免任何单一故障点,如下图所示:

显示 WPF 安全模型的图示。

本主题的其余部分讨论了与 WPF 相关的每个层的功能。

警告

新式 .NET 不支持代码访问安全性(CAS),它是仅限 .NET Framework 的概念。 所有与 CAS 相关的功能都根据完全信任的假设进行处理。 有关详细信息,请参阅 WPF .NET 的差异 - 代码访问安全性

操作系统安全性

Windows 的核心提供了几个安全功能,这些功能构成了所有 Windows 应用程序(包括使用 WPF 生成的安全功能)的安全基础。 本主题讨论这些对 WPF 非常重要的安全功能的广度,以及 WPF 如何与其集成以提供进一步的深度防御。

Microsoft Windows XP Service Pack 2 (SP2)

除了对 Windows 进行一般审查和加强之外,Windows XP SP2 还有三个关键功能,我们将在本主题中讨论:

  • /GS 编译

  • Microsoft Windows 更新。

/GS 编译

Windows XP SP2 通过重新编译许多核心系统库(包括 CLR 等所有 WPF 依赖项)来帮助缓解缓冲区溢出,从而提供保护。 这可以通过将 /GS 参数与 C/C++ 命令行编译器结合使用来实现。 尽管应该明确避免缓冲区溢出,但 /GS 编译提供了一种纵深防御的示例,用于防御可能因为无意或恶意操作而产生的潜在漏洞。

从历史上看,缓冲区溢出是许多高影响的安全攻击的原因。 当攻击者利用代码漏洞(允许注入写入缓冲区边界的恶意代码)时,会发生缓冲区溢出。 然后,攻击者可以通过覆盖函数的返回地址来劫持代码正在执行的进程,以导致执行攻击者的代码。 结果是恶意代码,它执行具有与被劫持进程相同的权限的任意代码。

在高级别上,-GS 编译器标志通过注入特殊的安全 Cookie 来保护具有本地字符串缓冲区的函数的返回地址,从而防止某些潜在的缓冲区溢出。 函数返回后,安全 Cookie 将与其以前的值进行比较。 如果值已更改,则可能发生了缓冲区溢出,并且进程已停止并出现错误条件。 停止进程可防止执行潜在的恶意代码。 有关更多详细信息 ,请参阅 -GS (缓冲区安全检查 )。

WPF 使用 /GS 标志进行编译,以向 WPF 应用程序添加另一层防御。

Windows Vista

Windows Vista 上的 WPF 用户将受益于作系统的其他安全增强功能,包括“Least-Privilege 用户访问”、“代码完整性检查”和特权隔离。

用户帐户控制 (UAC)

如今,Windows 用户倾向于使用管理员权限运行,因为许多应用程序需要它们进行安装或执行,或者同时需要这两者。 能够将默认应用程序设置写入注册表就是一个示例。

使用管理员权限运行实际上意味着应用程序从被授予管理员权限的进程执行。 其安全影响是,劫持使用管理员权限运行的进程的任何恶意代码都会自动继承这些特权,包括对关键系统资源的访问。

防范此安全威胁的一种方法是运行具有最少特权的应用程序。 这称为最低特权原则,是 Windows作系统的核心功能。 此功能称为“用户帐户控制”(UAC),由 Windows UAC 以两个关键方式使用:

  • 若要默认使用 UAC 权限运行大多数应用程序,即使用户是管理员;只有需要管理员权限的应用程序才能使用管理员权限运行。 若要使用管理权限运行,必须在应用程序清单中显式标记应用程序或作为安全策略中的条目。

  • 提供虚拟化等兼容性解决方案。 例如,许多应用程序尝试写入到受限位置,例如 C:\Program Files。 对于在 UAC 下执行的应用程序,存在不需要管理员权限写入的备用按用户位置。 对于在 UAC 下运行的应用程序,UAC 将 C:\Program Files 虚拟化,以便认为要向其写入的应用程序实际上正在写入另一个用户位置。 这种兼容性工作使作系统能够运行以前无法在 UAC 中运行的许多应用程序。

代码完整性检查

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

Browser-Hosted 应用程序的有限权限进程

浏览器托管的 WPF 应用程序在 Internet 区域沙盒中执行。 WPF 与 Microsoft Internet Explorer 的集成通过其他支持来扩展此保护。

警告

XBAP 要求旧版浏览器运行,例如 Internet Explorer 和旧版 Firefox。 这些较旧的浏览器通常在 Windows 10 和 Windows 11 上不受支持。 由于安全风险,新式浏览器不再支持 XBAP 应用所需的技术。 不再支持启用 XBAP 的插件。 有关详细信息,请参阅 有关 WPF 浏览器托管应用程序(XBAP)的常见问题解答。

由于 XAML 浏览器应用程序(XBAP)通常由 Internet 区域权限集沙盒化,因此从兼容性角度删除这些特权不会损害 XAML 浏览器应用程序(XBAP)。 而是创建一个额外的深层防御层;如果沙盒应用程序能够利用其他层并劫持进程,该进程仍将只有有限的权限。

请参阅 使用 Least-Privileged 用户帐户

公共语言运行时安全性

公共语言运行时(CLR)提供了许多关键安全优势,包括验证和验证、代码访问安全性(CAS)和安全关键方法。

确认和验证

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

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

托管应用程序编译为 Microsoft 中间语言(MSIL)。 执行托管应用程序中的方法时,其 MSIL 通过 Just-In-Time (JIT) 编译编译为本机代码。 JIT 编译包括一个验证过程,它应用了许多安全且可靠的规则,以确保代码不会:

  • 违反类型协定

  • 引入缓冲区溢出

  • 随意访问内存。

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

可验证代码的优点是 WPF 在 .NET Framework 上构建的主要原因。 在使用可验证代码的情况下,利用可能的漏洞的可能性会大幅降低。

代码访问安全性

客户端计算机公开了托管应用程序可以访问的各种资源,包括文件系统、注册表、打印服务、用户界面、反射和环境变量。 在托管应用程序可以访问客户端计算机上的任何资源之前,它必须具有 .NET Framework 权限才能执行此作。 CAS 中的权限是 CodeAccessPermission 的子类;CAS 为托管应用程序可以访问的每个资源实现一个子类。

当托管应用程序开始执行时,由 CAS 授予的权限集称为权限集,并由应用程序提供的证据确定。 对于 WPF 应用程序,提供的证据是启动应用程序的位置或区域。 CAS 标识以下区域:

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

  • 本地 Intranet。 从 Intranet 启动的应用程序。 (有点受信任)。

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

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

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

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

  • FullTrust。 对于从 “我的计算机” 区域启动的应用程序。 授予所有可能的权限。

  • LocalIntranet。 对于从 本地内联网区域内启动的应用程序。 授予一部分权限以提供对客户端计算机资源的中等访问权限,包括独立存储、不受限制的 UI 访问、不受限制的文件对话框、有限的反射、对环境变量的有限访问。 未提供关键资源(如注册表)的权限。

  • Internet。 对于从 Internet受信任的站点 区域启动的应用程序。 授予一部分权限,以便提供对客户端计算机资源的有限访问权限,包括独立存储、仅打开文件以及有限的 UI。 实质上,此权限集将应用程序与客户端计算机隔离开来。

标识为来自 “不受信任的站点” 区域的应用程序根本没有由 CAS 授予任何权限。 因此,预定义的权限集不存在。

下图说明了区域、权限集、权限和资源之间的关系:

显示 CAS 权限集的图。

Internet 区域安全沙盒的限制同样适用于 XBAP 从系统库(包括 WPF)导入的任何代码。 这可确保代码的每一个部分都得到保护,包括 WPF 在内。 遗憾的是,为了能够执行,XBAP 需要执行的功能要求比互联网区域安全沙箱允许的权限更多。

警告

XBAP 要求旧版浏览器运行,例如 Internet Explorer 和旧版 Firefox。 这些较旧的浏览器通常在 Windows 10 和 Windows 11 上不受支持。 由于安全风险,新式浏览器不再支持 XBAP 应用所需的技术。 不再支持启用 XBAP 的插件。 有关详细信息,请参阅 有关 WPF 浏览器托管应用程序(XBAP)的常见问题解答。

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

FileIOPermission fp = new FileIOPermission(PermissionState.Unrestricted);
fp.Assert();

// Perform operation that uses the assert

// Revert the assert when operation is completed
CodeAccessPermission.RevertAssert();
Dim fp As 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 支持这种情况,允许这些操作代表沙盒应用程序以提升的权限执行。 尽管所有 WPF 操作都根据 XBAP 应用程序域的有限 Internet 区域安全权限进行检查,但 WPF(与其他系统库一样)被授予一个权限集,该权限集包含所有可能的权限。

这要求 WPF 接收提升的权限,同时防止这些特权受主机应用程序域的 Internet 区域权限集控制。

WPF 通过使用权限的 Assert 方法执行此操作。 以下代码演示了这种情况的发生方式。

FileIOPermission fp = new FileIOPermission(PermissionState.Unrestricted);
fp.Assert();

// Perform operation that uses the assert

// Revert the assert when operation is completed
CodeAccessPermission.RevertAssert();
Dim fp As 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 负责正确使用断言;不正确使用断言可能会使恶意代码提升权限。 因此,请务必仅在需要时调用 Assert ,并确保沙盒限制保持不变。 例如,不允许沙盒代码打开随机文件,但允许使用字体。 WPF 允许沙盒应用程序通过调用 Assert 来使用字体功能,并使 WPF 能够读取已知代表沙盒应用程序包含这些字体的文件。

ClickOnce 部署

ClickOnce 是 .NET Framework 附带的综合部署技术,并与 Visual Studio 集成(有关详细信息,请参阅 ClickOnce 安全性和部署 )。 可以使用 ClickOnce 部署独立 WPF 应用程序,而必须使用 ClickOnce 部署浏览器托管的应用程序。

使用 ClickOnce 部署的应用程序通过代码访问安全性(CAS)提供额外的安全保护层,基本上,ClickOnce 部署的应用程序请求所需的权限。 如果不超过应用程序部署所在区域的权限集,则仅授予这些权限。 通过将权限集减少到仅需要的权限集,即使这些权限集小于启动区域的权限集提供的权限集,应用程序有权访问的资源数也会减少到最低。 因此,如果应用程序被劫持,则降低客户端计算机损坏的可能性。

Security-Critical 方法论

使用权限为 XBAP 应用程序启用 Internet 区域沙盒的 WPF 代码必须接受最高程度的安全审核和控制。 为了促进此要求,.NET Framework 为管理提升权限的代码提供了新的支持。 具体而言,CLR 使你能够识别提升权限的代码,并使用SecurityCriticalAttribute进行标记;而任何未标记为SecurityCriticalAttribute的代码,根据该方法都将变为透明。 相反,未使用 SecurityCriticalAttribute 标记的托管代码被禁止提升权限。

警告

XBAP 要求旧版浏览器运行,例如 Internet Explorer 和旧版 Firefox。 这些较旧的浏览器通常在 Windows 10 和 Windows 11 上不受支持。 由于安全风险,新式浏览器不再支持 XBAP 应用所需的技术。 不再支持启用 XBAP 的插件。 有关详细信息,请参阅 有关 WPF 浏览器托管应用程序(XBAP)的常见问题解答。

Security-Critical 方法允许组织将特权提升到 安全关键内核的 WPF 代码,其余部分是透明的。 隔离安全关键代码使 WPF 工程团队能够将额外的安全分析和源代码管理集中在高于和超越标准安全做法的安全关键内核上(请参阅 WPF 安全策略 - 安全工程)。

请注意,.NET Framework 允许受信任的代码扩展 XBAP互联网区域沙盒,通过允许开发人员编写被标记为 APTCA 的托管程序集,并将其部署到用户的全局程序集缓存(GAC)。 使用 APTCA 标记程序集是高度敏感的安全作,因为它允许任何代码调用该程序集,包括来自 Internet 的恶意代码。 执行此作时必须使用极端谨慎和最佳做法,用户必须选择信任该软件才能安装该软件。

Microsoft Internet Explorer 安全性

除了减少安全问题和简化安全配置之外,Microsoft Internet Explorer 6(SP2)还包含一些增强 XAML 浏览器应用程序用户安全性的功能(XBAP)。 这些功能的重点是试图让用户更好地控制其浏览经历。

警告

XBAP 要求旧版浏览器运行,例如 Internet Explorer 和旧版 Firefox。 这些较旧的浏览器通常在 Windows 10 和 Windows 11 上不受支持。 由于安全风险,新式浏览器不再支持 XBAP 应用所需的技术。 不再支持启用 XBAP 的插件。 有关详细信息,请参阅 有关 WPF 浏览器托管应用程序(XBAP)的常见问题解答。

在 IE6 SP2 之前,用户可能面临以下任一情况:

  • 随机弹出窗口。

  • 令人费解的脚本重定向。

  • 某些网站上的许多安全对话。

在某些情况下,不受信任的网站会尝试欺骗用户,欺骗安装用户界面(UI),或反复显示Microsoft ActiveX 安装对话框,即使用户可能已取消它。 使用这些技术,可能会有大量用户被诱骗做出了错误的决定,导致安装了间谍软件应用程序。

IE6 SP2 包括几个功能来缓解这些类型的问题,这些问题围绕用户启动的概念。 IE6 SP2 能够检测用户在执行操作之前是否点击了链接或页面元素,这称为用户启动,并与页面上脚本触发的类似操作区别对待。 例如,IE6 SP2 包含一个 Pop-Up 阻止程序 ,用于检测用户在创建弹出窗口之前单击按钮的时间。 这使 IE6 SP2 能够允许大多数无害的弹出窗口,同时阻止用户既不请求也不想要的弹出窗口。 被阻止的弹出窗口会显示在新的 信息栏下,并且信息栏允许用户手动取消阻止以查看这些弹出窗口。

同样的用户启动逻辑也应用于 “打开/保存” 安全提示。 ActiveX 安装对话框始终被信息栏拦截,除非它们是对已安装控件的升级。 这些措施结合在一起,为用户提供更安全、更受控的用户体验,因为它们受到保护,使其免受骚扰他们安装不需要或恶意软件的网站的影响。

这些功能还保护使用 IE6 SP2 浏览到允许其下载和安装 WPF 应用程序的网站的客户。 具体而言,这是因为 IE6 SP2 提供了更好的用户体验,可减少用户安装恶意或开发应用程序的机会,而不管使用何种技术来生成它,包括 WPF。 WPF 通过使用 ClickOnce 促进通过 Internet 下载其应用程序,从而增加了这些保护。 由于 XAML 浏览器应用程序(XBAP)在 Internet 区域安全沙盒中执行,因此可以无缝启动它们。 另一方面,独立 WPF 应用程序需要完全信任才能执行。 对于这些应用程序,ClickOnce 将在启动过程中显示一个安全对话框,以通知应用程序的其他安全要求的使用。 但是,这必须是用户启动的,也将受用户发起的逻辑的约束,并且可以取消。

Internet Explorer 7 将 IE6 SP2 的安全功能纳入并扩展为持续致力于安全性的一部分。

另请参阅