Allowing Partially Trusted Callers


The AllowPartiallyTrustedCallersAttribute (affectionately referred to as APTCA from here on out), is one of the aspects of the security system that most frequently trips people up when they run into it.  Lets look at a typical scenario where I might run into an issue with APTCA, and then we’ll be able to understand what it is and what it does.

Lets say I’m writing a class library to be used by many applications.  Following the standard library design guidelines, I’ve strongly named my library, and put it in the GAC.  So far nobody who’s used my library has had any problems.  However, someone in my company is building an application that’s being run from a network share, and they’re reporting a problem using my library.  Namely, any method that tries to call into my library isn’t running, its just failing with a security exception:

Unhandled Exception: System.Security.SecurityException: Security error.
   at Caller.Main()

What’s going on here?  By default, strongly named, fully trusted assemblies are given an implicit LinkDemand for FullTrust on every public and protected method of every publicly visible class.  Essentially, any code that someone outside of your assembly could use as an entry point into your code is protected with this demand.

Why do we do this?  One primary reason is to help prevent luring attacks where untrusted code can lure some fully trusted code into doing something dangerous on its behalf.  For instance, as an attacker, you look into my library and notice that in one of my methods I do an Assert for FileIOPermission, read its contents, and send them back to the caller.  You also notice that this method wasn’t carefully audited, and that there’s a way for you to control which file is read.  Now you can easily lure me into getting the contents of a file that you would not normally have been able to read.

OK, so lets assume that you’re a careful developer and are aware of potential security issues.  You’ve audited all your code that performs security critical actions, and you know for sure that you’re not susceptible to any luring attacks.  How can you remove the link demand so that partially trusted code can make use of the functionality you provide?

That’s where APTCA comes into play.  APTCA is an attribute that tells the CLR to remove the implicit LinkDemands mentioned above.  Once you’re sure your code is safe for untrusted callers to work with, apply APTCA to the assembly, and the LinkDemands will go away.  One important thing to note is that APTCA is only applicable on the assembly level, so you cannot disable these demands on a method-by-method or even  a class-by-class basis; either everything in the assembly is safe for partially trusted code to use, or none of it is.

Well, not exactly.  Since APTCA only removes the implicit LinkDemands,  any demands explicitly placed in your assembly will still be enforced.  This means that even once an assembly has been marked with APTCA, it could still have some types in it that are not usable from partial trust.  A list of types that ship with the .NET Framework, but still fall into that category can be found here.

When would you want to use apply APTCA?  Only if the following conditions all apply:

  1. Your code has been thoroughly audited for security vulnerabilities (perhaps using the MSDN Security Review Checklist)
  2. The code is in compliance with the Secure Coding Guidelines
  3. You specifically want partially trusted callers to use the library.  There’s no sense opening up an attack surface if you only care if fully trusted callers can use your code.

It’s interesting to note that not all of the framework assemblies are marked with APTCA. For instance, the v1.1 System..Security.dll is not callable from partially trusted code.  A list of assemblies that are callable from partial trust can be found about 2/3 of the way through this article, in the section entitled .NET Framework Assemblies with the AllowPartiallyTrustedCallersAttribute.

One final note about the exception text.  On v1.0 and v1.1, the exception pictured above isn’t the most helpful in the world when you’re trying to diagnose what went wrong.  With the work that went into increasing the usefulness of SecurityExceptions in Whidbey, we’ve also changed the error you get when you’re failing a LinkDemand due to APTCA.  Instead of “Security error.”, you’ll now see:

Unhandled Exception: System.Security.SecurityException: That assembly does not allow partially trusted callers.
   at Caller.Main()
The action that failed was:
LinkDemand
The assembly or AppDomain that failed was:
Caller, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
The method that caused the failure was:
Void TestMethod()
The Zone of the assembly that failed was:
MyComputer
The Url of the assembly that failed was:
file:///D:/blog/aptca/Caller.exe

Which is a lot more useful when trying to diagnose the error.

For more information, check out Using Libraries from Partially Trusted Code on MSDN.

Comments (31)

  1. Wraith says:

    One particular class in the exclusion list has caused me some headaches, FileVersionInfo. The documentation doesn’t tell you that it has a LinkDemand for full unrestricted permissions and because of the vaugeries of security exceptions in 1.x it was very hard to work out why my method kept failing.

    Is there any reason (or anyone/anywhere more appropriate to ask) why exactly FileVersionInfo requires totally unrestricted permissions? I ask because the thing preventing my using it was my using RequestRefuse on ReflectionEmit in my assembly, which really isn’t something that realistically prevents use of the class. In order to get around the restriction I implemented my own version of the class which only requires FileIO and UnmanagedCode permissions, it seems to work so I don’t see the need for the restriction on the CLR version which I would have preferred to use.

    At the very least it would be helpful if the classes that require extra security permissions were clearly marked in the documentation instead of only being listed under an article on a somewhat obscure Attribute that i wouldn’t even know to read about if it wasn’t for your very helpful blog.

  2. Shawn says:

    Hi Wraith,

    I’m not sure what that decision was made for the particular class. Decisions like these can be made based on a variety of criteria, ranging from a threat found during security testing or threat modling, to schedule pressures not allowing a thourough security test of the class to ensure it is safe to expose to partial trust.

    One place to check for the answer might be the BCL team’s blog. (http://blogs.msdn.com/bclteam)

    -Shawn

  3. Can we get Managed DirectX, or at least the simple rendering of primitives to APTC? It’s frustrarting not being able to use MDX9 via ClickOnce with all the possibilities there…

  4. Shawn says:

    Hi Judah,

    Well, that’s up to the DX team. It may very well be their design decision to not allow DirectX (which allows pretty close control of the hardware) from partial trust. However, that absolutely does not remove the chance to use DX9 in a ClickOnce scenario. In fact, due to the permission elevation feature of ClickOnce, you can simply say "my app needs full trust". Then if the user grants FullTrust, you’ll be able to use DX since you’ll meet the APTCA link demands.

    -Shawn

  5. Sergey Koshcheyev says:

    What if I don’t have any permission assertions in my library? Is it then safe to allow partially trusted callers to use it? Or can you think of a scenario where this would be insecure?

  6. Steve Flaum says:

    I’m getting the error message "That assembly does not allow partially trusted callers" when calling a method in the same assembly. That is, a VB.Net Sub running in the Visual Studio 2005 debugger raises that error when it tries to call a Sub in another module in the same project and assembly. How can that be?

  7. Steve Flaum says:

    It turns out that the problem was that I had moved my project to a network drive. When I moved it back to a local drive, the error message went away.

    ‘ strange message for that problem.

  8. One of the V1 decisions we made was to not allow partially trusted callers in our policy framework. …

  9.    

           The GetCustomAttributes scenario (ICustomAttributeProvider.GetCustomAttributes

         …

  10. Haibo just posted an excellent article about what happens when you use reflection to get a custom attribute…

  11. Gump's blog says:

    The exception mentioned in the title of this post was the one I encountered when using an ASP.Net…

  12. John says:

    What if the calling assembly is not on a network share…!? It is only accessing SQL Server. Does that make it partially untrusted? Why?

  13. Any code that is not granted FullTrust is partially trusted.  If your code is hosted within SQL Server, then it likely is partially trusted.

    -Shawn

  14. Last year, I explored the ins and outs of the AllowPartiallyTrustedCallersAttribute.  Today, the…

  15. David Walker says:

    Just HOW do you "apply APTCA to the assembly"???  The "more information" link you posted is broken.

  16. Shawn says:

    The link seems to work for me.  To apply APTCA, just add the AllowPartiallTrustedCallersAttribute to your assembly:

    [assembly: AllowPartiallyTrustedCallers]

    -Shawn

  17. Shawn says:

    The link seems to work for me.  To apply APTCA, just add the AllowPartiallTrustedCallersAttribute to your assembly:

    [assembly: AllowPartiallyTrustedCallers]

    -Shawn

  18. shreeman says:

    Shawn,

    Wouldnot it be Better to Provide a better Description of the Security Error so that one can understand that he is facing a LinkDemand issue or it is not possible to determine that this indeed was due to LinkDemand BeforeHand OR this is by design to not provide any further description here.Although the exception is a security exception one don’t ve any mean to diagnost these.

  19. Absolutely a better error message would help things out.  That’s why in v2.0 you now get the message about "That assembly does not allow partially trusted callers."  in order to help diagonose the problem with APTCA.

    -Shawn

  20. Sid DeLuca says:

    If you’re having problems with the attribute on the assembly, you may need to qualify the value with the Security namespace:

    (vb)

  21. John says:

    So what do I do if I’m using a third party assembly? For example, I tried deploying the MySql Connector assembly to my web server but I get the "System.Security.SecurityException: That assembly does not allow partially trusted callers." exception. What do I do now?

  22. Doods says:

    Shawn – I must be missing something here because i’ve spent the entire day trying to follow one guideline after another on how to make my website work but still end up unsuccessfull.

    My website is written in VB 2.0, using MySQL database and the MySQL Provider (mysql.data.dll) to connect to the db tables.  My business logic and data access are together in a class that resides in the App_Code folder.

    Just above this class I added the "AllowPartiallTrustedCallersAttribute" signature (<Assembly: AllowPartiallyTrustedCallers()> ).

    I still end up with a security exception as follows:

    [SecurityException: That assembly does not allow partially trusted callers.]

      oradude.Poetry.GetPoemTitles() +0

    I am getting hopeless here and would really appreciate your help.

    Thanks.

    Doods

  23. It would appear that either the assembly containing the oradude object, the return value of hte Poetry property or the return value of GetPopemTitles() is not marked APTCA.  I would start by checking those out.

    -Shawn

  24. In the case of third party assemblies, you’ll need to contact the developer.  In many cases (such as non-APTCA assemblies from Microsoft), the assemblies have not been tested under partial trust and may not be safe for arbitrary untrusted code to call.

    -Shawn

  25. Il'ya says:

    I have the same problem as Doods does: I’ve added [assembly: AllowPartiallyTrustedCallers()] to AssemblyInfo.cs file (I use C#), but still have that Security Exception. May be the problem is in MySql.Data.dll?

  26. APTCA needs to be applied to the assembly which is being called.  So if your code is calling into MySql.Data, then MySql.Data will need APTCA.

    -Shawn

  27. okman says:

    is there any cahnge  in  senario after version

    .net version 2.0 and 3.5 have been releaced?

  28. No, this behaves the same in all released versions of the .NET framework (at this point that’s through v3.5 SP1).

  29. chessfan says:

    I am adding the .dll for a library that does not allow partially trusted callers into my C# project. When I go to modify the assembly directives, I’m unable to modify anything that’s in the screen. How do I get permissions to modify the assembly directives?

    Another reference even includes the attribute I want:

    System.Security.AllowPartiallyTrustedCallersAttribute

    But if I try to type or paste this into the window for my .dll, I’m not allowed to.