如何将.net程序集标记为安全?

Ian*_*oyd 18 c# assemblies

我如何将装配标记为"安全"?

或者,我如何让Visual Studio告诉我何时装配中的某些内容不"安全"?


有时您不能使用程序集,除非它是"安全的"(例如从SQL Server).

我希望我的装配被标记为安全.如果我的装配不能被标记为安全,因为它不安全,我想知道我怎么知道我的装配是不安全的.


Visual Studio中有一些概念似乎与安全性有关,可能与组件"安全"有关,也可能没有任何关系:

  1. 允许不安全的代码汇编选项:

    在此输入图像描述

    • 如果我检查允许不安全的代码选项,允许什么?
    • 如果我取消选中允许不安全的代码选项,那么该怎么办?
    • "不安全代码"与"安全"程序集有什么关系(如果有的话)?

      (我问,因为我的程序集不"允许不安全的代码",但允许P/Invoke调用 - 我认为这是"不安全"的定义)

  2. ClsCompliant程序集选项:

    [assembly: CLSCompliant(true)]
    namespace MyApplication
    
    Run Code Online (Sandbox Code Playgroud)
    • "cls兼容"代码与"安全"程序集有什么关系(如果有的话)?
  3. 不安全的代码块:

    int error;
    unsafe
    {
        error = 0x80004005;
    }    
    
    Run Code Online (Sandbox Code Playgroud)

    unsafe块内的代码是"不安全的"

  4. UnsafeNativeMathods

    Microsoft建议创建一个UnsafeNativeMethods包含不安全托管代码的类:

    [SuppressUnmanagedCodeSecurity]
    internal static class UnsafeNativeMethods
    {
       ...          
    }
    
    Run Code Online (Sandbox Code Playgroud)

    这与以下形成对比SafeNativeMethods:

    [SuppressUnmanagedCodeSecurity]
    internal static class SafeNativeMethods
    {
       ...          
    }
    
    Run Code Online (Sandbox Code Playgroud)

    包含安全的本机方法,并且NativeMethods:

    internal static class SafeNativeMethods
    {
       ...          
    }
    
    Run Code Online (Sandbox Code Playgroud)

    包含本机方法.

我如何将装配标记为"安全"?

SQL如何知道汇编"不安全"?

Eri*_*ert 26

我如何将装配标记为"安全"?

你正在考虑这个错误的方法.

你认为可能想杀死你的人会给你一个瓶子然后说"喝这个".你说"喝酒安全吗?" 那家伙说"读瓶子".你做.它上面写着"安全饮用".

你喝了吗?

液体是否可以安全饮用与瓶子上的标签所说的无关!将汽油放入标有"安全饮用"的瓶子中是完全可能的.

你是那个把装满可疑液体的瓶子分发给SQL服务器的人,而SQL Server说"我不相信你要在这个装配上放置任何标签".相反,它将通过限制组件可以做什么来使组件"安全".它会锁定该事物的权限,以便程序集利用SQL服务器的任何尝试都将导致它通过异常终止.

我如何知道我的装配中的某些东西不是"安全"的?

尝试以低信任度运行它.它是否因安全异常而崩溃并死亡?如果答案是肯定的,那么根据该信任级别它是不安全的.不同的信任级别授予不同级别的权限.您在自己的计算机上安装的代码通常完全受信任,您从公司网络运行的代码不太受信任,您从互联网运行的代码根本不受信任.您在SQL Server中运行的代码对所有人的信任程度最低; 它认为几乎一切都是不安全的.

如果我检查允许不安全的代码选项,允许什么?

然后,您可以编写直接以其选择的方式操作原始指针到内存的代码.这需要完全信任; 如果您希望使用不安全的代码,则必须对您的程序集没有任何限制.不安全的代码可以在此过程中更改用户模式内存的每一位.

"cls兼容"代码与"安全"程序集有什么关系(如果有的话)?

除了CLS兼容代码不允许采用原始指针类型的API之外,没有任何其他事实.

CLS是公共语言子集 - 所有兼容的.NET语言中必须存在的一组功能.这样你就不必问自己"嘿,如果我写这个接受int的方法并在C#中返回一个字符串,我可以用F#调用它吗?" 如果您限制自己遵守CLS的规则,那么您就知道任何CLS语言都可以使用您的库,并且您可以使用符合CLS的库,无论它们使用何种语言编写.它与安全性无关.

不安全块内的代码是"不安全的"

如果写得不好,不安全块内的代码可能会在整个过程中任意破坏内存.我们会让您将代码标记为"不安全",以便您知道在哪里集中代码审核工作.在不安全的块中,而不是C#语言负责确保类型和内存安全.

你没问的一个问题:

将程序集标记为"对部分可信赖的调用者是安全的"是什么意思?

这是你的情况标记的组件,"安全".通过使用AllowPartiallyTrustedCallerAttribute(APTCA)标记程序集,程序集的作者,断言如果程序集中的代码被试图攻击用户的低信任恶意代码调用,那么程序集中没有任何内容低信任恶意代码可以用来对付用户.简而言之,您说"即使用户完全信任,我的代码也不是邪恶代码可以对用户使用的武器".

我们发明了APTCA,因为在当天,Peter Torr和我发现有一种方法可以让那些信任度低的恶意调用者欺骗JScript.NET代码 - 默认情况下是高度信任 - 以这种方式低信任代码可能导致JScript.NET代码代表它攻击用户.(这通常被称为"引诱攻击",因为低信任代码"诱使"高信任代码为其执行脏工作.)

作为确保此类错误不再发生的大量努力的一小部分,CLR团队引入了APTCA.通过将APTCA放在程序集上,您告诉您的用户您声称他们对您的工作的信任不会被恶意的第三方代码滥用.除非(1)您打算通过用户认为可能具有敌意的代码调用程序集,并且(2)您实际上已经进行了彻底的安全审查,否则不要将APTCA放在程序集上.

幸运的是,新的基于透明度的安全模型消除了对APTCA的大部分需求.

如果程序集中不存在APTCA,则"链接请求"将确保调用程序集的代码完全受信任.请注意,这是一个链接需求,而不是一个完整的需求.


Tig*_*ran 12

  • 从阅读,"安全"为SQL Server是:

SAFE是限制性最强的权限集.具有SAFE权限的程序集执行的代码无法访问外部系统资源,如文件,网络,环境变量或注册表

所以它在SQL Server代码域中设置代码执行权限

  • Unsafe来自VS的标志无关,基本上,具有代码执行安全性,但允许非托管代码执行.所以这就非托管代码集成到托管代码库中

  • CLS Compilant属性定义这里是有关定义的代码标有类似的如下CSL(通用语言规范)准则的码该属性的组件.所以关于编译和代码架构.

我如何将装配标记为"安全"?

它在本答案的第一个链接中定义,并与SQL Server集成有关.

SQL如何知道汇编"不安全"?

考虑提供的描述:"创建一个托管应用程序模块,其中包含类元数据和托管代码作为SQL Server实例中的对象",SQL Server继续metadata,在某些字段中提供有关事实的信息,如果它是"安全的"或不.

  • 还可以注意到,在创建程序集时可以设置程序集的"Permission_Set".来自`CREATE ASSEMBLY` [文档](http://msdn.microsoft.com/en-us/library/ms189524.aspx):PERMISSION_SET {SAFE | EXTERNAL_ACCESS | UNSAFE} (2认同)