Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access a security critical field from an anonymous delegate or lambda?

Scenario

Let's say we've the next code:

[SecuritySafeCritical]
public void SomeMethod()
{
    SomeCriticalClass critical = new SomeCriticalClass();

    Action someDelegate = () => 
    {
         critical.Do();
    }

    someDelegate();
}
  1. The SomeMethod signature has [SecuritySafeCritical] attribute.
  2. SomeCriticalClass is some class that has the [SecurityCritical] attribute either in the class or method Do method-level.
  3. We create an anonymous delegate auto-inferred to Action.

Problem

Calling critical.Do() causes a MethodAccessException FieldAccessException because a security transparent method (the anonymous method) is trying to access a security critical field (the critical SomeCriticalClass local variable).

Question

How you overcome this?

The easy way would be implementing an actual method marked with [SecuritySafeCritical] instead of using an anonymous delegate. But this moves us to pre-anonymous delegates and lambas era. I don't want this.

Other easy way would be just don't using security transparency. This isn't a solution.

Almost any available libraries both from Microsoft and open source community aren't designed with security transparency in mind. That is, any own custom code must interoperate with third-party libraries through [SecuritySafeCritical] or [SecurityCritical] methods/properties/delegates.

Actually I believe that security transparency is a good tool because it forces better and secure software designs, critical actions are very localized and the rest of the code works with minimal permissions.

like image 347
Matías Fidemraizer Avatar asked Dec 19 '12 16:12

Matías Fidemraizer


1 Answers

Sorry but I couldn't wait for other answerers... I got the solution!

By experimentation I could determine that marking with [SecuritySafeCritical] the class having the method that creates the anonymous method in its body, does the trick!!

In other words, or talking about the code:

[SecurityCritical]
public class SomeCriticalClass
{
      [SecurityCritical]
      public void Do()
      {
      }
}

[SecuritySafeCritical]
public sealed class SomeClass
{
    [SecuritySafeCritical]
    public void SomeMethod()
    {
          SomeCriticalClass critical = new SomeCriticalClass()

          // No more FieldAccessException!
          Action action = () => critical.Do();         
    }
}

I want to make some clarifications:

  • Marking the class SomeClass with [SecuritySafeCritical] doesn't mean that all declared methods will be [SecuritySafeCritical] by default. It means that the class can be used by partially-trusted callers. You still need to mark with [SecuritySafeCritical] attribute those methods, properties or fields that can be accessed by partially-trusted callers.

  • It seems that [SecuritySafeCritical] at class-level makes local variables and anonymous methods (maybe anonymous objects too!) security safe critical.

Yes! I hope both my question and my own answer will be useful for everyone, because I believe that the situation described in my question can happen often!

like image 70
Matías Fidemraizer Avatar answered Oct 14 '22 06:10

Matías Fidemraizer