XAML 安全注意事项
本文介绍使用 XAML 和 .NET XAML 服务 API 时保证应用程序安全性的最佳做法。
应用程序中不受信任的 XAML
从最普遍意义上来说,不受信任的 XAML 是应用程序未专门包含或发出的任何 XAML 源。
在受信任且已签名的程序集中编译或存储为 resx
类型资源的 XAML 本质上不是不受信任的。 你可以像信任整个程序集一样信任该 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 的几个属性的具体说明。