SecurityPermission question

V

Victor Hadianto

Hi all,

Newbie in this Code Access Security thing, I'm rather lost how to use
it. I've Googled through and still a bit confused. What I want to do
is simply this:

[SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)]
class ClassSecurity
{
public void Foo()
{
Console.WriteLine("SUCCESS");
}
}

Now I have another class to call the ClassSecurity's method:


class Class1
{
public void CallingMethod()
{
try
{
ClassSecurity cs = new ClassSecurity();
cs.Foo();
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}

I would expect that the cs.Foo() would fail as I don't declare any
security attribute on Class1. But it doesn't. Is this a misuse of the
SecurityPermission class? How should I implement the CAS to make
Class1 throws an exception when calling ClassSecurity?

Thanks,
Victor
 
R

Richard Blewett

Victor Hadianto said:
Hi all,

Newbie in this Code Access Security thing, I'm rather lost how to use
it. I've Googled through and still a bit confused. What I want to do
is simply this:

[SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)]
class ClassSecurity
{
public void Foo()
{
Console.WriteLine("SUCCESS");
}
}

Now I have another class to call the ClassSecurity's method:


class Class1
{
public void CallingMethod()
{
try
{
ClassSecurity cs = new ClassSecurity();
cs.Foo();
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}

I would expect that the cs.Foo() would fail as I don't declare any
security attribute on Class1. But it doesn't. Is this a misuse of the
SecurityPermission class? How should I implement the CAS to make
Class1 throws an exception when calling ClassSecurity?

Thanks,
Victor

Hi Victor,

what you have coded is that ClassSecurity can only be accessed by code
running with full trust. Now CAS runs over the top of the inbuilt windows
security infrastructure so essentially what you have said is that the
calling code must not be restricted further by CAS over the windows
permission granted by the token the code is running with (what they can do
because of who the process is running as).

The idea of CAS is to allow further restriction over and above what windows
will do based on the *origins* of the code. The origins may be: where it was
loaded from, who wrote it (strong name or code signing cert) or a number of
other factors. In general where the code was loaded from is the main arbiter
and this is configured by default on internet explorer zones. So code loaded
from the local machine gets full trust, code loaded from intranet get some
restrictions, code loaded from internet zone gets more restrictions, etc.

As your calling code was (I assume) loaded from the local machine - your C:
drive for example - it will be running with fulltrust and therefore will be
able to call ClassSecurity without issue. If you go into the project
settings and enable partial trust using the security tab, when you run your
code under the debugger you should see your SecurityException

--
Regards

Richard Blewett
DevelopMentor
http://www.dotnetconsult.co.uk/weblog2
 
V

Victor Hadianto

Hi Richard,

As your calling code was (I assume) loaded from the local machine - your C:
drive for example - it will be running with fulltrust and therefore will be
able to call ClassSecurity without issue. If you go into the project
settings and enable partial trust using the security tab, when you run your
code under the debugger you should see your SecurityException

Ah I see, looks like I misunderstood the concept of
SecurityPermission. So is there a way, assuming the assemblies are
running full trust, to check which class is calling Foo() and
implements some sort of check whether they have some attributes set?

Thanks,
Victor
 
R

Richard Blewett

Victor Hadianto said:
Hi Richard,



Ah I see, looks like I misunderstood the concept of
SecurityPermission. So is there a way, assuming the assemblies are
running full trust, to check which class is calling Foo() and
implements some sort of check whether they have some attributes set?

Thanks,
Victor

Getting the caller of your method is not hard - just a bit expensive

StackFrame sf = new StackFrame(1);

Heres an example

class Program
{
static void Main(string[] args)
{
Foo f = new Foo();
f.FooMethod();
f.AnotherFooMethod();
}
}

class Foo
{
[MyAttribute]
public void FooMethod()
{
Bar b = new Bar();
b.BarMethod();
}
public void AnotherFooMethod()
{
Bar b = new Bar();
b.BarMethod();
}
}

class Bar
{
public void BarMethod()
{
StackFrame sf = new StackFrame(1);
Console.WriteLine(sf.GetMethod().Name);

bool attrDefined = sf.GetMethod().IsDefined(typeof(MyAttribute), false);
if( attrDefined)
Console.WriteLine("MyAttribute was defined");
else
Console.WriteLine("MyAttribute was not defined");
}
}

class MyAttribute : Attribute
{
}

--
Regards

Richard Blewett
DevelopMentor
http://www.dotnetconsult.co.uk/weblog2
 
R

Richard Blewett

Victor Hadianto said:
Hi Richard,



Ah I see, looks like I misunderstood the concept of
SecurityPermission. So is there a way, assuming the assemblies are
running full trust, to check which class is calling Foo() and
implements some sort of check whether they have some attributes set?

Thanks,
Victor

Hi Victor,

you can do this with the StackFrame class - although it is comparetively
expensive. It depends on how often you need to do this

class Program
{
static void Main(string[] args)
{
Foo f = new Foo();
f.FooMethod();
f.AnotherFooMethod();
}
}

class Foo
{
[MyAttribute]
public void FooMethod()
{
Bar b = new Bar();
b.BarMethod();
}

public void AnotherFooMethod()
{
Bar b = new Bar();
b.BarMethod();
}
}

class Bar
{
public void BarMethod()
{
StackFrame sf = new StackFrame(1); // the 1 indicates direct caller
(0 would be this method itself)
Console.WriteLine(sf.GetMethod().Name);

bool attrDefined = sf.GetMethod().IsDefined(typeof(MyAttribute),
false);
if( attrDefined)
Console.WriteLine("MyAttribute was defined");
else
Console.WriteLine("MyAttribute was not defined");
}
}

class MyAttribute : Attribute
{
}

--
Regards

Richard Blewett
DevelopMentor
http://www.dotnetconsult.co.uk/weblog2
 
V

Victor Hadianto

Hi Victor,

you can do this with the StackFrame class - although it is comparetively
expensive. It depends on how often you need to do this

Thanks it looks simple enough to implement. How is it more expensive
than standard security attributes? Don't these also do a stack walk to
ensure the permissions? Instinctively (mine anyway) a simple
StackFrame(1) would be less costly.

Regards,
Victor
 
R

Richard Blewett

http://www.dotnetconsult.co.uk/weblog2
Victor Hadianto said:
Thanks it looks simple enough to implement. How is it more expensive
than standard security attributes? Don't these also do a stack walk to
ensure the permissions? Instinctively (mine anyway) a simple
StackFrame(1) would be less costly.

Regards,
Victor

Well I would imagine the process of walking the stack is cheaper than the
actual stack trace purely because its implemented in the CLR not by the
class library. However the other mitigation generally used by the class
library, because of the cost of the stackwalk, is to only perform the
security check in the constructor of an object - assuming that objects will
not be passed into a different CAS context once created. I'm not sure,
however, if this approach will work for you
 
J

Jeroen Mostert

Victor said:
Hi Richard,



Ah I see, looks like I misunderstood the concept of
SecurityPermission. So is there a way, assuming the assemblies are
running full trust, to check which class is calling Foo() and
implements some sort of check whether they have some attributes set?
Note that if your calling code is *also* running under full trust, this is a
pointless exercise. Full trust code can do anything it likes, including
faking its stack frame or reflecting your code, copying it and removing the
check -- it's not easy, but it's not that hard either.

It's called "full trust" for a reason. If you can't trust your callers, they
shouldn't be running as full trust. Your code can't ensure that, and that's
not its job either. CAS is a good solution for when *partially* trusted
callers need to be additionally restricted.

If you need real protection from outside callers and you can't control their
trust level, you need to put a process or even a machine barrier between you
and them, and rely on external authentication methods. Of course, these
things get costlier the less you can trust your callers and the more
security you need.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top