A Suggestion For A New Access Modifier

As .NET languages don’t have friendship (or anything in the vicinity), the Internal modifier has come into play.
I had a conversation about this with AmiD a while back and we came to the conclusion that we need a new access modifier, since Internal is too limited (we have to create our own unexposed assembly to assembly interop).
So here I am suggesting the Trusted modifier. This modifier will be checked not against containment in the same Assembly, but against having the same strong name.

What does this mean?
It means that if I have two assemblies, let’s say:
Omer.A, Version=, Culture=, PublicKeyToken=b03f5f7f11d50a3a
Omer.B, Version=, Culture=, PublicKeyToken=b03f5f7f11d50a3a
(Note that both Assemblies are signed with the same key)

Using the Internal modifier on a member in Assembly Omer.A, I could access it from anywhere in the same Assembly.
Using the Trusted modifier on a member in Assembly Omer.A, I could access it from anywhere in both Assembly Omer.A and Assembly Omer.B, since they share the key.

I think this to be extremely useful, especially for application suites created by the same manufacturer.

Update: Paul Wilson has informed me that this already exists in the form of an attribute. I still think it would be best if this was part of the .NET languages.

Update: Jim Hogg explains in the comments about a new feature, Friend Assemblies, and catches lots of people’s attention.

Advertisements

5 thoughts on “A Suggestion For A New Access Modifier

  1. There are two types of Publisher Identity security that could be used to
    help secure the application:

    PublisherIdentityPermission – this class prohibits calling
    applications from accessing an assembly if it does not have the correct
    X.509v3 certificate.

    StrongNameIdentityPermission – this class prohibits calling
    applications from accessing an assembly if it does not have the specified
    strong-name.

  2. Paul,

    I am the first to admit that I know little about security in .NET. I have looked through the MSDN looking for the class and attribute and found them to be, as far as I can see, what I had asked for.
    However, IMHO, this is would be best if incorporated into the language in a simple way.

  3. Omer,

    It’s possible to "work around" this issue by making the Types in Omer.A that you want to access, by making them public, but then reigning back on access using a SNIP (Strong-Name-Identity-Permission). But this is ugly, and confusing!

    So, we intend to introduce a new feature in next release of .NET — "Friend Assemblies", that does precisely what you’re suggesting. It will use an assembly-level custom attribute called "InternalsVisibleTo", that grants access to a named "friend" assembly (Omer.B in this example) — for all "internal" types.

    As well as making the CLR loader ‘understand’ this attribute, compilers need to ‘understand’ it too, of course.

    Jim

  4. Jim,

    First of all, let me say I’m honored to have someone of your stature read my humble .net blog. Thank you :)

    I have read and re-read your post and find it both comforting and disturbing at the same time. Comforting because this is a feature I have wanted for quite a while, yet disturbing due to the fact that it is not the way I have imagined it.
    Doing what you’re saying would require me to re-compile my whole assembly library set if I require just one more assembly added to it.
    Sure, you may say that’s the way life goes and that we’re better off having to do that to keep tabs on everyone that uses the assemblies, but what if there are 1000 assemblies and I want to add one more? That would cause me to have to change all 1000 assemblies, recompile them and re-distribute them to my clients.

    My suggestion was to eliminate this problem by using the strong name key to determine which assemblies were created by me, so that I know I can trust them with my internal code.

    Please do not read this the wrong way, as I appreciate this new feature greatly :)

  5. Omer,

    Yes, you would need to explicitly add an extra "friendship" custom attribute and recompile.

    Granting "friendship" is not something to be done lightly. If the other assembly were written by a different group in your team, for example, you would want to audit their every use of friendship before granting it. To see what can go wrong, think of a public method in Omer.A, which performs a security demand, and then calls another "internal" method. What if the guy who wrote Omer.B used friendship to call that internal method directly? — bypassing the security demand?

    Your suggested design — automatically grant friendship to all assemblies signed with the same public key — would indeed avoid the need for recompiles. But we deliberately chose not to go there. Indeed, there was a strong push to limit friendship even more tightly — granting class-by-class, or even method-by-method, rather than whole assembly.

    Hope this throws light on why we chose the current design. Essentially, it’s all about making it harder for devs to accidentally create a security hole.

    Jim

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s