.NET 指南:Demand VS LinkDemand

安全声明提供了两种类似的安全检查来完成不同的任务。你应该理解这两种形式,因为错误的选择能够削弱安全性或者损失性能。关于更多信息,请参考:[安全要求]。

安全声明提供了下列安全检查:

  • Demand 指定了代码访问安全堆栈通道。堆栈的所有调用者都必须拥有被指定的许可或者要通过的身份。Demand 在每个调用的时候都会产生,因为堆栈可能包含了不同的调用者。如果你重复地调用同一个方法,那么在每次调用期间都会产生安全检查。Demand 能够很好地保护不会受到诱导攻击;未被授权的代码尝试通过它来进行获取的操作都将被发现。
  • LinkDemand 发生在即时(JIT)编译的时候并且只检查直接的调用者。这个安全检查并不会检查调用者的上级调用者。一旦这个检查被通过,那么不论调用者可能会调用多长时间,都不会存在额外的安全管理。但是,这同样没有对来自于诱导攻击进行保护。使用 LinkDemand,任何传递测试并且能够对你的代码进行引用的代码都能够潜在地允许恶意代码来调用被授权的代码,从而会破坏安全。因此,不要使用 LinkDemand,除非所有可能的弱点能够彻底地被避免。

在使用 LinkDemand 而必须单独被编程的时候,额外防范才是必需的;安全系统能够有助于执行。并且任何一种过失都可能公开一个安全弱点。所以对你的代码进行使用的所有被授权代码都必须是可靠的,在为了通过下列步骤而实现额外的安全的情况下:

  • 约束调用代码对于类或者汇编集的访问。
  • 把相同的安全检查存放到出现在被调用代码以及对其行为进行负责的调用者代码中。例如,如果你编写代码来调用一个为指定了 UnmanagedCode 标记的 SecurityPermission 并且以 LinkDemand 而被保护的方法,那么你的方法就同样应该为了这个许可而使用一个 LinkDemand(或者是更强大的 Demand)。例外的情况就是如果你的代码在你认为是安全的一种被限制的方式中使用了被 LinkDemand 保护的方法,在你的代码中给予其他的安全保护机制(如 Demand)。在这种例外的情况中,调用者会在底层的代码中为弱点承担相应的责任。
  • 确保你的代码的调用者不能够为了他们的利益而欺骗你的代码来调用任何被保护的代码。换句话说,调用者不能够强制未被授权的代码来传递特殊的参数到被保护的代码中,或者是从被保护的代码中获取执行结果。

接口与链接需求

如果一个虚拟方法、属性,或者事件以 LinkDemand 而重载了一个基类的方法,为了保证它是有效的,那么基类的方法就同样必须为这个重载方法而拥有相同的 LinkDemand。但是这有可能被恶意代码用来追溯基类型并且调用基类的方法。同样要注意的是:链接需求能够被隐式地添加到没有 AllowPartiallyTrustedCallersAttribute 汇编集级别特性的汇编集中。

在接口的方法同样拥有链接需求的时候,保护使用链接需求的方法实现就是一个好的实践。注意:下列关于为接口而使用链接需求的情况。

  • AllowPartiallyTrustedCallersAttribute 特性同样适用于接口。
  • 你能够把链接请求存放到接口中来有选择性地对通过部分被信任的代码而被使用的的特定接口进行保护(比如在使用 AllowPartiallyTrustedCallersAttribute 特性的时候)。
  • 如果你有一个接口被定义在一个没有包含 AllowPartiallyTrustedCallersAttribute 特性的汇编集中,那么你就可以在部分的被信任类中实现这个接口。
  • 如果你把 LinkDemand 存放在实现了接口方法的类的公开方法中,那么 LinkDemand 就不再是被强制的,如果这时候你转换接口并且调用了方法。在这种情况下,因为你链接了反向接口,所以只有接口的 LinkDemand 才是被承认的。

为安全问题而回顾下列内容:

  • 接口方法中明确的链接需求。并确保这些链接需求提供了所期望的保护。检测是否恶意代码能够使用转换来获取前面所描述的链接需求。
  • 应用了链接需求的虚拟方法。
  • 它们所实现的类型与接口。这些都应该使用一致的链接需求。

你可能感兴趣的:(.net)