有人可以解释在子类化 Windows 控件时出现的 LinkDemand 警告吗?

2024-03-23

我有这个 HeaderlessTabControl,它是经典 TabControl 的子类。

// From http://social.msdn.microsoft.com/forums/en-US/winforms/thread/c290832f-3b84-4200-aa4a-7a5dc4b8b5bb/
// Author: Hans Passant (nobugz)
public class HeaderlessTabControl : TabControl {
    protected override void WndProc(ref Message m) {
        // Hide tabs by trapping the TCM_ADJUSTRECT message
        if (m.Msg == 0x1328 && !DesignMode) {
            m.Result = (IntPtr)1;
        } else {
            base.WndProc(ref m);
        }
    }
}

当我在项目上运行代码分析时,我收到以下警告:

警告 1 CA2122:Microsoft.Security: “HeaderlessTabControl.WndProc(ref Message)”调用 具有 LinkDemand 的“Message.Msg.get()”。通过拨打此电话, “Message.Msg.get()”间接暴露给用户代码。回顾 以下调用堆栈可能会暴露规避安全性的方法 保护:->'HeaderlessTabControl.WndProc(参考消息)'
->'HeaderlessTabControl.WndProc(参考消息)'

...以及两个类似的警告Message.Msg.set() and TabControl.WndProc()。我知道我通过这样做暴露了一些代码。有人可以解释一下我可能在这里打开了什么样的安全漏洞,以及可能的修复方法吗?


我想我要问的是,我应该寻找哪些可能的安全漏洞?

让我用五分钟的时间概述一下“传统”.NET 代码访问安全性。 (我们有一个更新的、简化的安全模型,应该用于新代码,但了解底层安全模型是有帮助的。)

这个想法是组件提供evidence——诸如它们所在的位置、作者是谁等等。Policy消耗evidence并产生一个补助金集 of 权限与该程序集相关联。

当尝试执行需要特定权限的操作(例如,创建对话框或访问打印机或写入文件)时,运行时会发出demand以获得该许可。该需求检查当前“堆栈上”的代码以确定所有代码called直接或间接地当前代码。 (*)

需求说的是堆栈上的每个调用者都必须已被授予所需的权限。这可以防止引诱攻击,恶意的低信任代码调用良性的高信任代码并“引诱”它代表其执行一些危险操作,以伤害用户。由于全面需求检查直接和间接调用者引诱攻击由此被击败。

An assert允许高信任代码修改需求语义。断言说“我是良性的高信任代码,并且我断言我不会被低信任的敌对调用者引诱代表其执行危险操作。”断言通常与较弱的需求配对;也就是说,高信任代码断言“即使调用者不能,我也可以安全地调用非托管代码”,然后要求“但调用者最好有访问打印机的权限,因为这就是我要对我的非托管代码执行的操作”代码许可”。

需求的问题在于它们是昂贵的。您必须进行完整的堆栈遍历并查看每个人的权限集。如果操作成本较低(例如,调整位图中的像素),您不想每次都执行完整的要求,因为您将花费所有时间进行冗余的安全检查。

就这样链接需求。执行链接请求每个受保护方法的调用者一次, the 第一次使用调用受保护方法的代码,并且它只检查受保护方法的直接调用者,而不是进行完整的堆栈遍历。之后,执行链接要求的代码操作,不进行安全检查对于那个来电者。 (它确实应该被称为“jit 需求”,而不是“链接需求”,因为使用的机制是当调用者紧张时,将检查需求。)

显然,这要便宜得多——每个调用者只检查一个程序集的一张检查比一张检查便宜per call那个看着堆栈上的每个程序集 -- and 更危险的方式.

链接需求基本上是相互推诿。链接需求说“呼叫者,通过我的链接需求检查,从现在开始您可以以便宜的价格给我打电话。但是我现在关闭安全系统,因此you现在负责确保你的来电者以后不能利用我授予你在没有安全检查的情况下给我打电话的权利来成功攻击用户。”

您正在调用具有链接需求的方法。所以你面临的问题是:你愿意承担这个责任吗?您可以以便宜的价格调用该方法。你愿意吗保证没有低信任的恶意调用者可以利用您在没有安全检查的情况下调用该方法的事实来伤害用户?

如果您不愿意或无法做出这样的保证,那么提出自己的要求对于链接所需的许可;然后要求所有呼叫者满足要求。或者,把责任推给your调用者:发出链接请求your呼叫者并拨打them做工作。


(*) 正如我喜欢指出的那样,调用堆栈实际上并没有告诉你谁给你打电话,它告诉你接下来控制将走向何方。既然那些是usually同样的事情,一切都很顺利。最终可能会陷入“谁给你打电话?”的情况。已经脱离了“你下一步要去哪里?”;在这些环境中,您必须非常小心地使用传统风格的代码访问安全性。较新的“沙盒”安全模型更适合这些场景。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

有人可以解释在子类化 Windows 控件时出现的 LinkDemand 警告吗? 的相关文章

随机推荐