4

I'm currently trying to build a custom code access security solution for our project.

Therefore i created a CustomPermissionAttribute which should be used as shown:

[CustomPermissionAttribute(SecurityAction.Demand, Permission="PermMethodABC")]
public void MethodABC() 
{ 
}

The CreatePermission() method of the Attribute creates and returns a new CustomPermission instance.

The Demand Method of the CustomPermission class should check the security against my custom IPrincipial Implementation in Thread.Current.CurrentPrincipial:

public sealed class CustomPermission : IPermission
{
    private string _RequiredPermission;
    ...
    public void Demand()
    {
        ICustomPrincipial _pr = Thread.Current.CurrentPrincipial as ICustomPrincipial;
        if (_pr == null) throw...
        if (!_pr.HasPermission(_RequiredPermission)) throw...
    }
}

public interface ICustomPrincipial : IPrincipial
{
    bool HasPermission(string RequiredPermission);
}

All above is in the signed "Assembly A".

The unsigned Assembly B contains the following CustomPrincipial implementation which implements ICustomPrincipial of Assembly A:

public sealed class CustomPrincipial : ICustomPrincipial
{
    User _User;
    ...
    public bool HasPermission(string RequiredPermission)
    {
        if (_User has permission defined with "PermMethodABC") ...
        return true/false;
    }
    ...
}

(Now Assembly A has to know anything about the User-type. If i place the CustomPrincipial class into Assembly A, then all Assemblys with the user stuff also would have to be signed... otherwise i cannot compile Assembly A)

On Application startup, a new instance of the CustomPrincipial is assigned to Thread.Current.CurrentPrincipial.

Two Questions:

  • Could saftey problems caused by the public ICustomPermission interface in Assembly A?

  • Is it absolutely necessary to fully implement all IPermission Members? Especially the ToXML and FromXML Methods... The CreatePermission() Method gets anyway invoked everytime i access MethodABC() at runtime.

EDIT: ad 1: I'm thinking of the following situation: "Assembly C" contains MethodXY which is protected with a CustomPermissionAttribute. To get access to this protected Method, an attacker could create a new application, references to Assembly A & Assembly C and could make an own implementation of the public ICustomPrincipial interface of Assembly A (-> HasPermission() returning true all the time). He could assign an instance of his implementation to his own Thread.Current.CurrentPrincipial. If Assembly A's Demand() Method checks against Thread.Current.CurrentPrincipial an attacker could get access to MethodXY. That might be a possible situation..!?

Christian
  • 143
  • 8

1 Answers1

1

Could saftey problems caused by the public ICustomPermission interface in Assembly A?

Assuming you are careful with your permissions, Thread.Current.CurrentPrincipal should be read-only to most other programs, making bypassing impossible. (At least from a quick glance at the MSDN page)

However as with any security issue it is probably best to test yourself. Try and write code that runs in your environment and implements its own way of bypassing CurrentPrincipal.

Is it absolutely necessary to fully implement all IPermission Members? Especially the ToXML and FromXML Methods... The CreatePermission() Method gets anyway invoked everytime i access MethodABC() at runtime.

There is an example on the msdn page of a full implementation, it doesn't look too nasty to do, and would guarantee you don't have problems later on due to a NotImplementedException.

However I haven't experimented enough with IPermission to know what methods are called during normal operations.

EDIT: This is more of a comment, but a little long.

One of the important things to keep in mind is that if a piece of code has the permissions to modify the principal there isn't too much you can do to stop it from bypassing any of your permissions. SecurityPermissionFlag.ControlPrincipal is the permission that setting the CurrentPrincipal demands. I believe unless you use a tool such as Caspol.exe any executable will by default run under full trust.

To sum it up, by default the .NET framework assumes custom code is fully trusted until it is told otherwise. If you are calling code you don't trust, there are mechinisms to ensure that code runs with lower security credentials, or if you have an executable you don't trust then you can lower its security credentials. However any administrator of the machine has more than enough power to bypass any code access security that you implement (as you commented with your IPrincipal override).

If this doesn't explain well enough let me know and I can add more detail.

Guvante
  • 18,775
  • 1
  • 33
  • 64
  • According to safety: I have mentioned a possible situation in my post above. According to IPermission: During normal operations just IsSubsetOf() and Demand() are called. – Christian Jun 01 '12 at 07:06