This is cache of http://pluralsight.com/blogs/keith/archive/2007/12/03/49343.aspx. Cache is the snapshot of article that we took when we index feed.
To see original page click here.
We are not affiliated with the authors of this article and not responsible for its content.
PrincipalPermissionAttribute and Static ctor Leads to DoS
2007-12-03 09:03:00 by Keith Brown in Security Briefs
 

I recently heard a colleague lamenting that he was having difficulty using PrincipalPermissionAttribute at the class level in a certain scenario under WCF. I recommended caution in my guidebook, because of the nasty type load exception that you can run into if the first request to the class is denied by the attribute.

Be careful about using this attribute at the class level. If the class to which you apply it happens to have a static constructor (or, even worse, if it may get one in the future), realize that this attribute applies to the static constructor as well! Why is this a problem? Well, if a static constructor throws an exception, the class is latched into a mode where each future attempt to call the static constructor leads to the previous exception being rethrown (Brumme, 2003). So, if the first caller to use the class doesn't satisfy the permission demand, no callers in the entire AppDomain will be able to use that class!

Here's a simple console app you can compile that demonstrates the danger.

using System;
using System.Security.Principal;
using System.Security.Permissions;
using System.Threading;

[PrincipalPermission(SecurityAction.Demand, Role="SuperUser")]
class Sensitive {
    static Sensitive() {
        Console.WriteLine("Inside static constructor");
    }
}

class Program {
    static void Main(string[] args) {
        becomeSuperUser();
        tryUsingSensitiveClass();
        becomeNormalUser();
        tryUsingSensitiveClass();
    }
    static void tryUsingSensitiveClass() {
        try {
            new Sensitive();
            Console.WriteLine("{0} OK!!",
                Thread.CurrentPrincipal.Identity.Name);
        }
        catch (Exception x) {
            Console.WriteLine(
                "{0} failed due to a {1}",
                Thread.CurrentPrincipal.Identity.Name,
                x.GetType().Name);
        }
    }
    static void becomeNormalUser() {
        Thread.CurrentPrincipal = new GenericPrincipal(
            new GenericIdentity("Bob"), null);
    }
    static void becomeSuperUser() {
        string[] roles = { "SuperUser" };
        Thread.CurrentPrincipal = new GenericPrincipal(
            new GenericIdentity("Alice"), roles);
    }
}

Here's the output of the above program, exactly as written. Notice that the call order is such that the privileged user accesses the protected class first, so things work as you'd expect:

Inside static constructor
Alice OK!!
Bob failed due to a SecurityException

Here's the output when I switch the order and have the normal user try to use the class first. The type is locked down and after that, even privileged users can't access it:

Bob failed due to a TypeInitializationException
Alice failed due to a TypeInitializationException

If you remove the static ctor, things work as expected:

Bob failed due to a SecurityException
Alice OK!!

Does this mean that you should never use PrincipalPermissionAttribute on a class? Maybe not, but you should probably put a comment on the class warning future devs to avoid adding a static ctor on it.

 
 
 
 
 
 
TOP SEARCH
Expand / MinimizeClose Widget
  •  
RECENT SEARCH
Expand / Minimize
  •  
RELATED VIDEO
Expand / Minimize
SecurityRatty FAQ
Sergey Zarubin, 31yo
CISSP, CCSP
Moscow, Russia