ASP.NET Lab

The Best Web, The Best Future

博客园 首页 新随笔 订阅 管理

有些库代码需要调用未被管理的代码,例如,本地代码 API(如 Win32)。因为这表示被管理的代码已经超出了安全范围之外,因此适当的谨慎是必需的。如果你的代码是属于安全中立的,那么你的代码与任何对它进行调用的代码都必须拥有未被管理的代码许可(指定了 UnmanagedCode 标记的 SecurityPermission)。

但是,让你的调用者拥有如此强大的许可通常是不合理的。在这种情况下,你的被信任代码能够成为中间媒介,并且类似于被管理包装或者在[保护包装代码]中被描述的库代码。如果底层的未被管理代码的功能是完全安全的,那么它就能够直接被暴露;否则,就必须首先执行一个适当的许可检查(Demand)。

在你的代码调用了未被管理的代码但是你又不想要求你的调用者拥有访问未被管理代码的许可的时候,你必须对那个权利进行声明。但是,声明会阻碍你的框架中的堆栈通道。因此你必须保持谨慎,不要在这个处理中创建一个安全漏洞。通常,这表示你必须要求一个适当的调用者许可然后使用未被管理的代码来完成那些只在许可所允许的范围之内的任务。在有些情况下(例如,一个获取当天时间的功能),未被管理的代码能够不需要任何的安全检查就直接被暴露给调用者。在任何情况下,任何代码声明都必须承担相应的安全责任。

因为任何为本地代码而提供代码路径的未被管理代码都能够成为恶意代码的潜在目标,因此,确定哪些未被管理的代码能够安全地被使用并且它应该如何被使用是必需的。通常,未被管理的代码从不应该被直接地暴露给部分被信任的调用者。有两种主要的考虑事项来评估在能够被部分被信任代码调用的库中使用的未被管理代码的安全性:

  • 功能。

    这是未被管理 API 所提供的不允许调用者来完成潜在的危险操作的功能。代码访问安全使用许可来强制对于资源的访问,因此需要考虑 API 是否使用了文件、用户界面、或者线程,或者它是否暴露了被保护的信息。如果情况属实,那么被管理代码就会对它进行包装并且在允许它被开始之前要求所必需的许可。另外,虽然没有通过许可而被保护,但是对于内存的访问则必须是被限制的并且以此来严格化类型的安全性。

  • 参数检查。

    一个公共的攻击会把不可预料的参数传递给被暴露的未被管理代码的 API 方法来导致它们完成非常规的任务。使用了超范围的索引或者偏移值的缓存溢出就是这种攻击的一种公共范例,它与任何可能对底层代码的缺陷进行利用的参数是一样的。因此,即使未被管理代码 API 对于部分被信任的调用者来说是功能安全的(在必需的要求之后),被管理的代码同样必须检查属性的正确性,并用尽一切方式来确保不使用被管理的代码包装层从恶意代码中出现无意识的调用。

posted on 2007-02-11 19:33  Laeb  阅读(219)  评论(0编辑  收藏  举报