如何将程序集标记为“安全”?
你思考这个问题的方式是错误的。
你认为可能想杀你的人递给你一个瓶子并说“喝这个”。你说“喝安全吗?”那家伙说“读一下瓶子”。你做。上面写着“安全饮用”。
你喝吗?
液体是否可以安全饮用与瓶子上的标签无关!完全可以将汽油放入标有“安全饮用”的瓶子中。
你就是那个把装满可疑液体的瓶子交给 SQL 服务器的人,并且 SQL Server 说“我不信任您要在此程序集上添加的任何标签”。相反,它将通过限制程序集可以执行的操作来使程序集“安全”。它锁定该事物的权限,以便程序集利用 SQL Server 的任何尝试都将导致其通过异常终止。
我如何知道程序集中的某些内容不“安全”?
尝试以低信任度运行它。它是否因安全异常而崩溃并死亡?如果答案是肯定的,那就不安全根据该信任级别。不同的信任级别授予不同级别的权限。您在自己的计算机上安装的代码通常是完全可信的,您从公司网络运行的代码不太可信,您从互联网运行的代码几乎根本不可信。您在 SQL Server 中运行的代码获得的信任级别最低;它认为几乎一切都是不安全的。
如果我选中允许不安全代码选项,可以执行什么操作?
然后,您可以编写代码,以自己选择的方式直接操作指向内存的原始指针。这需要充分的信任;必须有no如果您希望使用不安全的代码,则对您的程序集施加限制。不安全代码可以更改进程中用户模式内存的每一位。
“cls 兼容”代码与程序集“安全”有什么关系(如果有的话)?
无论如何,除了符合 CLS 的代码不允许采用原始指针类型的 API 之外。
CLS 是公共语言子集——所有兼容的 .NET 语言中都需要存在的一组功能。这样您就不必问自己“嘿,如果我在 C# 中编写这个接受 int 并返回字符串的方法,我可以从 F# 中调用它吗?”如果您限制自己遵守 CLS 规则,那么您就知道任何 CLS 语言都可以使用您的库,并且您可以使用符合 CLS 的库,无论它们是用什么语言编写的。它与安全性没有任何关系。
unsafe 块内的代码是“不安全”的
如果写得不好,不安全块内的代码可能会在整个过程中任意破坏内存。我们让您将代码标记为“不安全”,以便您知道将代码审查工作集中在哪里。在不安全的区块中you, not C# 语言,负责确保类型和内存安全。
一个你没有问过的问题:
将程序集标记为“对于部分受信任的调用者来说是安全的”意味着什么?
在这种情况下,您do将程序集标记为“安全”。通过使用AllowPartiallyTrustedCallerAttribute (APTCA) 标记程序集,您(程序集的作者)断言,如果程序集中的代码由试图攻击用户的低信任恶意代码调用,则程序集中没有任何内容低信任度的敌对代码可以使用它来攻击用户。简而言之,您是在说“即使用户完全信任,我的代码也不是邪恶代码可以用来对付用户的武器”。
我们发明了 APTCA,因为当时 Peter Torr 和我发现,对于信任度较低的恶意调用者来说,有一种方法可以欺骗 JScript.NET 代码(默认情况下信任度很高),以这样的方式,信任代码可能会导致 JScript.NET 代码代表其攻击用户。 (这通常称为“引诱攻击”,因为低信任代码“引诱”高信任代码为其完成肮脏的工作。)
作为确保此类错误不再发生的巨大努力的一小部分,CLR 团队引入了 APTCA。通过将 APTCA 放在程序集中,您就告诉用户您正在声明他们对您的工作的信任不会被敌对的第三方代码滥用。请勿将 APTCA 放在组件上,除非 (1)intend对于用户认为可能有敌意的代码调用的程序集,以及 (2) 您实际上已经进行了彻底的安全审查。
幸运的是,新的基于透明度的安全模型消除了对 APTCA 的大部分需求。
如果程序集中不存在 APTCA,则“链接需求”将确保调用程序集的代码是完全可信的。请注意,它是一个链接需求, not a 满需求.