XAML 安全注意事项
本文介绍使用 XAML 和 .NET XAML 服务 API 时应用程序中安全性的最佳做法。
应用程序中不受信任的 XAML
从最普遍意义上说,不受信任的 XAML 是应用程序未专门包含或发出的任何 XAML 源。
编译为或存储为受信任和签名程序集中的 resx
类型资源的 XAML 本质上不受信任。 可以像信任整个程序集一样信任 XAML。 在大多数情况下,你只关注松散 XAML 的信任方面,它是从流或其他 I/O 加载的 XAML 源。 松散 XAML 不是具有部署和打包基础结构的应用程序模型的特定组件或功能。 但是,程序集可能实现涉及加载松散 XAML 的行为。
对于不受信任的 XAML,应将其一般视为不受信任的代码。 使用沙盒或其他隐喻来防止可能不受信任的 XAML 访问受信任的代码。
XAML 功能的性质使 XAML 有权构造对象并设置其属性。 这些功能还包括访问类型转换器、映射和访问应用程序域中的程序集、使用标记扩展、x:Code
块等。
除了语言级别功能外,XAML 还用于许多技术的 UI 定义。 加载不受信任的 XAML 可能意味着加载恶意欺骗 UI。
在读者和编写器之间共享上下文
适用于 XAML 读取器和 XAML 编写器的 .NET XAML 服务体系结构通常需要将 XAML 读取器共享到 XAML 编写器或共享 XAML 架构上下文。 如果要编写 XAML 节点循环逻辑或提供自定义保存路径,则可能需要共享对象或上下文。 不要在受信任代码和不受信任的代码之间共享 XAML 读取器实例、非默认 XAML 架构上下文或 XAML 读取器/编写器类的设置。
大多数涉及针对基于 CLR 的类型支持编写的 XAML 对象的方案和操作只能使用默认的 XAML 架构上下文。 默认 XAML 架构上下文不会显式包含可能危及完全信任的设置。 因此,在受信任和不受信任的 XAML 读取器/编写器组件之间共享上下文是安全的。 但是,如果这样做,最好让此类读者和编写器在单独的 AppDomain 范围内,其中一个专门用于部分信任/沙盒。
XAML 命名空间和程序集信任
XAML 如何解释到程序集的自定义 XAML 命名空间映射的基本不限定语法和定义不区分加载到应用程序域中的受信任程序集和不受信任的程序集。 因此,在技术上,不受信任的程序集可以欺骗受信任程序集的预期 XAML 命名空间映射,并捕获 XAML 源的声明对象和属性信息。 如果存在避免这种情况的安全要求,则应使用以下方法之一进行预期的 XAML 命名空间映射:
在应用程序 XAML 进行的任何 XAML 命名空间映射中使用具有强名称的完全限定程序集名称。
通过为 XAML 读取器和 XAML 对象编写器构造特定的 XamlSchemaContext,将程序集映射限制为固定的引用程序集集。 请参阅 XamlSchemaContext(IEnumerable<Assembly>)。
XAML 类型映射和类型系统访问
XAML 支持自己的类型系统,在很多方面都是 CLR 如何实现基本 CLR 类型系统的对等。 但是,对于类型感知的某些方面,你根据类型信息对类型做出信任决策时,应延迟 CLR 支持类型中的类型信息。 这是因为 XAML 类型系统的一些特定报告功能作为虚拟方法保持打开状态,因此不受原始 .NET XAML 服务实现的控制。 由于 XAML 类型系统是可扩展的,因此存在这些扩展点,以匹配 XAML 本身的可扩展性及其可能的替代类型映射策略与默认 CLR 支持的实现和默认 XAML 架构上下文。 有关详细信息,请参阅有关 XamlType 和 XamlMember的多个属性的具体说明。