Code Permission - Should I write a custom "Friend Permission" (or does it exist)??

  • Thread starter Thread starter Phil Jones
  • Start date Start date
P

Phil Jones

Should I be writing a custom <Permission> attribute that prevents any code,
other than code from within a class's containing assembly to call it?

OR - is there some inbuilt framework permission/mechanism for doing that.
It seems like a pretty common thing that everyone would want to do a lot, so
I thought I'd ask before I rolled by own.

Many thanks.

===
Phil
(Auckland | Aotearoa)
 
Hello Phil,

If I understand your question correctly, I believe what you are looking for
is the Friend modifier. Marking a Class, Method, etc. with Friend makes that
object available to the assembly it is packaged with, but nothing outside of
that.
 
My concern (as was pointed out to me a few psts back on this list) is that
Friend is still accessible via Reflection - which means it's not secure,
it's just not visible.

What I think I need to do is adorn the method (or Class etc) with a
code-access-security permission. Something that actually walks the stack to
make sure the calling procedure actually is a Friend.

This seems like it'd be such a common requirement (ie. when I declare
Friend, I really mean Friend, in the securist sense) that the framework
would provide for it. Maybe not - but I just wanted to check.

Thanks Chris.
===
Phil
(Auckland | Aotearoa)
 
Hi Phil,

Currently I am looking for somebody who could help you on it. We will reply
here with more information as soon as possible.
If you have any more concerns on it, please feel free to post here.


Thanks for your understanding!




Peter Huang
Microsoft Developer Community Support
Email :[email protected]

This posting is provided "AS IS", with no warranties, and confers no rights.
 
Phil Jones said:
My concern (as was pointed out to me a few psts back on this list) is that
Friend is still accessible via Reflection - which means it's not secure,
it's just not visible.

What I think I need to do is adorn the method (or Class etc) with a
code-access-security permission. Something that actually walks the stack
to make sure the calling procedure actually is a Friend.

This is one possible approach, but you should be careful not to subclass
System.Security.CodeAccessPermission if you want to ensure that your
permission is not trivially bypassed by disabling CAS. You might also want
to keep in mind that it is relatively simple to decompile an assembly,
remove the permission demands, and recompile. Depending on what kind of
threat you attempting to protect against, this may make the permission
approach far too much bother for the level of protection it provides.

This seems like it'd be such a common requirement (ie. when I declare
Friend, I really mean Friend, in the securist sense) that the framework
would provide for it. Maybe not - but I just wanted to check.

You'll probably find StrongNameIdentityPermission demands recommended for
this in at least a few places. However, they're easily bypassed by fully
trusted code, so they may not suit your goals. Basically, there's nothing
built into CAS to truly protect any given code from being called by fully
trusted code. If you are considering rolling your own protection mechanism,
I'd recommend a licensing approach rather than a CAS permission approach.
While licensing will be a bit more difficult and time-consuming to
implement, you'll be able to use it more widely than a permission that
merely checks that callers are in the same assembly.
 
Hey thanks Nicole - I appreciate your insights into this whole issue.

Basically I'm concerned about a remoting server I have. I basically only
want known clients making certain calls to it. If someone can get at the
server and decompile my assembly I have bigger problems to worry about.

I'm thinking that if I write some custom permission that checks for the
strong name identity of the calling assembly (or whatever mechanism makes
sense when I get may head around CAS).

You make an intersting point about disabling the CAS. This would probably
not be an issue as long as the server is secure - right? Same deal as
above.

Many thanks
 
If you can consider your server to be safe from direct meddling, you don't
need to worry about a client directly disabling CAS on your server.
However, that still wouldn't necessarily make SNIP
(StrongNameIdentityPermission) a good choice here. For starters, I have
serious doubts regarding whether a SNIP demand would cross a remoting
boundary. However, even if it could, it still wouldn't be trustworthy since
disabling CAS is not the only trivial way to cheat a SNIP check. For
example, in your remoting scenario, a malicious caller could delay sign his
own spoofing assembly with your public key then enable verification skipping
for the assembly on his own client machine.

In a way, the above is really just one example of the more general problem:
servers cannot trust clients. No matter what kind of mechanism you try to
put into place to help a server validate the client code's identity, an
attacker will be able to find a workaround since the server essentially
treats the client as a black box. If malicious code can adequately mimic
responses coming out of that black box, your server will not be able to
distinguish between it and a legitimate client.

The main implications of this are:

1. Servers should never trust that any client-provided data has been
validated on the client. All data should be re-validated, even if the
expected client will have pre-screened the data it submits to the server.

2. Servers should never use the self-declared identity of calling code as a
criterion when determining server-side permissions. The user's identity
should be used instead, and this identity should be communicated to the
server in a manner that minimizes the chances of spoofing by the caller.
(e.g.: Windows integrated authentication would be a lot safer than passing
the user name as a parameter to a server-side method.)

In addition to the above protections, you may wish to implement a licensing
scheme, but its main purpose should be preventing unlicensed client
machines, not unlicensed assemblies, from calling your server. Basically,
once a license (or any other "caller ticket") is available on a client
machine, it will become possible for a malicious user to use that license to
call your server.

BTW, on the side issue of authoring a custom permission, it's not generally
worthwhile either. The main reason for implementing this sort of check as a
permission in the first place is usually to enable the user of declarative
security statements (i.e.: permission attributes) in order to add
corresponding demands to one's code. However, permission attributes are
only used by the .NET Framework if their containing assembly has been
designated as a policy assembly in the running machine's security policy
configuration. Therefore, in order to bypass declarative demands for a
custom permission, a malicious user merely needs to remove the assembly
declaring the permission attribute from the local policy assemblies list.
Once this is done, your code will run as if the declarative demands were not
present at all.
 
Beautiful - thank you for such a thorough background on all of this. Much
appreciated Nicole.
===
Phil
 
Back
Top