Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mark a .net assembly as safe?

Tags:

c#

assemblies

How do i mark as assembly as "safe"?

Alternatively, how do i have Visual Studio tell me when something in my assembly is not "safe"?


Sometimes you cannot use an assembly unless it is "safe" (e.g. from SQL Server).

i would like my assembly to be marked as safe. If my assembly cannot be marked as safe because it's not safe, i'd like to know how i can know that my assembly is not safe.


There are some concepts in Visual Studio that seem to relate to safe-ness, that may or may not have anything to do with an assembly being "safe":

  1. Allow unsafe code assembly option:

    enter image description here

    • What is allowed if i check the allow unsafe code option?
    • What is not allowed if i uncheck the allow unsafe code option?
    • What relation, if any, does "unsafe code" have to do with an assembly being "safe"?

      (i ask because my assembly doesn't "allow unsafe code", but allows P/Invoke calls - which i thought was the definition of "unsafe")

  2. ClsCompliant assembly option:

    [assembly: CLSCompliant(true)]
    namespace MyApplication
    
    • What is the relation, if any, does "cls compliant" code have to do with an assembly being "safe"?
  3. unsafe code block:

    int error;
    unsafe
    {
        error = 0x80004005;
    }    
    

    The code inside the unsafe block is "unsafe"

  4. UnsafeNativeMathods

    Microsoft recommends creating a class called UnsafeNativeMethods that contain unsafe managed code:

    [SuppressUnmanagedCodeSecurity]
    internal static class UnsafeNativeMethods
    {
       ...          
    }
    

    This contrasts with SafeNativeMethods:

    [SuppressUnmanagedCodeSecurity]
    internal static class SafeNativeMethods
    {
       ...          
    }
    

    that contains safe native methods, and NativeMethods:

    internal static class SafeNativeMethods
    {
       ...          
    }
    

    that contain native methods.

How do i mark as assembly as "safe"?

How does SQL know that as assembly is "not safe"?

like image 498
Ian Boyd Avatar asked Jan 09 '12 21:01

Ian Boyd


People also ask

How do you secure an assembly?

You can sign an assembly in two different but complementary ways: with a strong name or by using SignTool.exe (Sign Tool). Signing an assembly with a strong name adds public key encryption to the file containing the assembly manifest.

How do you secure assemblies in an application?

Using Strong Names The primary way to protect your assemblies from attack is to attach a strong name. Strong names are pairs of keys (strings of numbers)—one private and one public. The private key is held inside the assembly and is inaccessible.

How can I make my assembly name strong?

In Solution Explorer, open the shortcut menu for the project, and then choose Properties. Under the Build tab you'll find a Strong naming node. Select the Sign the assembly checkbox, which expands the options. Select the Browse button to choose a Strong name key file path.

What does signing an assembly mean?

Signing an assembly ensures that the consumer knows its origin and uniquely identifies the component. It makes the physical DLL file tamper-proof. This tutorial will step you through signing an assembly with a strong name key (SNK) in . NET.


1 Answers

How do i mark as assembly as "safe"?

You're thinking about this the wrong way.

Someone who you think maybe wants to kill you hands you a bottle and says "drink this". You say "is it safe to drink?" The guy says "read the bottle". You do. It says "SAFE TO DRINK" on it.

Do you drink it?

Whether the liquid is safe to drink or not has nothing whatsoever to do with what the label on the bottle says! It is perfectly possible to put gasoline in a bottle marked "SAFE TO DRINK".

You're the guy handing out the bottle full of suspicious liquid to SQL server, and SQL Server says "I don't trust any label you're going to put on this assembly". Rather, it is going to make the assembly "safe" by restricting what the assembly can do. It locks down the permissions on that thing so that any attempt by your assembly to take advantage of SQL server will result in its termination via an exception.

How do I know when something in my assembly is not "safe"?

Try running it in low trust. Did it crash and die with a security exception? If the answer is yes, then it wasn't safe according to that trust level. Different trust levels grant different levels of permissions. Code you install on your own machine is typically fully trusted, code you run from your corporate network is less trusted, code you run from the internet is hardly trusted at all. Code you run in SQL server gets the least level of trust of all; it thinks almost everything is unsafe.

What is allowed if i check the allow unsafe code option?

You can then write code that directly manipulates raw pointers to memory in a manner of its choosing. That requires full trust; there must be no restrictions placed upon your assembly if you wish to use unsafe code. Unsafe code can change every bit of user-mode memory in the process.

What is the relation, if any, does "cls compliant" code have to do with an assembly being "safe"?

None whatsoever, other than the fact that CLS compliant code does not allow for APIs that take raw pointer types.

CLS is the Common Language Subset -- the set of features that are required to be present in all compliant .NET languages. That way you don't have to ask yourself "hey, if I write this method that takes an int and returns a string in C#, can I call it from F#?" If you restrict yourself to follow the rules of the CLS then you know that any CLS language can use your library, and you can use CLS-compliant libraries no matter what language they were written in. It has nothing whatsoever to do with safety.

The code inside the unsafe block is "unsafe"

The code inside the unsafe block can arbitrarily corrupt memory throughout the process if it is written badly. We make you mark code like that "unsafe" so that you know where to concentrate your code reviewing efforts. In an unsafe block you, not the C# language, are responsible for ensuring type and memory safety.

A question you did not ask:

What does marking an assembly as "safe for partially trusted caller" mean?

This is a situation where you do mark an assembly as "safe". By marking an assembly with the AllowPartiallyTrustedCallerAttribute (APTCA) you, the author of the assembly, are asserting that if the code in the assembly is called by low-trust hostile code that is attempting to attack the user, then there is nothing in your assembly which the low-trust hostile code can use against the user. In short, you are saying "even if fully trusted by the user, my code is not a weapon that evil code can use against the user".

We invented APTCA because back in the day, Peter Torr and I discovered that there was a way for hostile callers who had low trust to trick the JScript.NET code -- which was high trust by default -- in such a way that the low trust code could cause the JScript.NET code to attack the user on its behalf. (This is usually called the "luring attack" because the low-trust code "lures" the high-trust code into doing its dirty work for it.)

As just one small part of a large effort to ensure that this sort of mistake did not happen again, the CLR team introduced APTCA. By putting APTCA on an assembly, you are telling your users that you are making the claim that their trust of your work is not abusable by hostile third party code. Do not put APTCA on an assembly unless (1) you intend for the assembly to be called by code the user believes may be hostile, and (2) you have actually done a thorough security review.

The new transparency based security model obviates much of the need for APTCA, fortunately.

If APTCA is not present on an assembly then a "link demand" will ensure that the code which invokes your assembly is fully trusted. Note that it is a link demand, not a full demand.

like image 101
Eric Lippert Avatar answered Sep 26 '22 01:09

Eric Lippert