0

This is a follow-up for this question.

I have a security sensitive class A and a hierarchy of wrappers that use it (classes B and ChildOfB). B must initialize an instance of A and allow ChildOfB to use it. The instance of A should be accessible only to B and ChildOfB, which is exposed to other assemblies and can not be internal.

The code sample:

// ************* Library assembly *************
internal class A {}

public abstract class B
{
    // compiler error: Inconsistent accessibility: property type 
    // 'Library.A' is less accessible than property 'Library.B.Property'    
    protected A Property { get; private set; }
}

public sealed class ChildOfB : B
{
    public ChildOfB()
    {
        Console.WriteLine(Property);
    }
}


// ************* in some other assembly *************
var wrapper = new ChildOfB();

As far as I know there is no way to do it in plain C#. I am OK with a solution that uses an external tool, that might modify a dll after compilation (for example based on some attributes). For example in my code the property will be internal instead of protected and after the compilation this tool may change CLR type definition to include missing flags (the result should have family and assembly access modifier). It also would be great if this tool insures that changing property's access modifiers does not break any code in the initial dll.

Community
  • 1
  • 1
Aleksei Poliakov
  • 1,322
  • 1
  • 14
  • 27
  • 2
    `protected` and `internal` are _accessibility_ modifiers. They have absolutely nothing to do with security. – H H Nov 29 '13 at 09:33
  • I have added `security sensitive` part only to avoid people advising 'to make everything public and do not bother' – Aleksei Poliakov Nov 29 '13 at 10:01
  • 1
    This is all quite misguided. What use is a tool? Whomever wants to make the call just isn't going to use the tool. Look at the [InternalsVisibleTo] attribute and the StackTrace class. – Hans Passant Nov 29 '13 at 10:01
  • @Hans The caller will not have to use the tool, it will will be triggered as post-build event on the library project. This is the only way I can think of to get the expected result, if there are other ways I am glad to hear them – Aleksei Poliakov Nov 29 '13 at 10:09
  • Then the security remark is just confusing and misleading. The protected property is the design flaw, redesign the interaction between B and ChildOfB. But making `A` public is a valid solution too. – H H Nov 29 '13 at 13:40
  • 1
    I'd rather use a static analyzer that checks if the class is used elsewhere in the assembly keeping the visibility at `internal`. But personally I don't think the gain over `internal` is big. At some point you need to rely on the programmer not to do dumb stuff. – CodesInChaos Nov 29 '13 at 14:23
  • 1
    @AlexeyPolyakov , aka DarkWalker : maybe you need to have your accounts merged? – H H Nov 29 '13 at 19:39
  • @CodesInChaos could you post this as an answer so I can accept it? This solution is good enough, we already use FxCop for static analysis, so it should not be hard to write a custom rule. – Aleksei Poliakov Nov 30 '13 at 06:49

2 Answers2

1

If this is only about preventing accidental mistakes, not about security, you could use a static analyzer to enforce this rule. Set the visibility to internal and have the analyzer emit a warning/error when those classes are used in ways you don't like.

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
1

Since C# 7.2 there is construct private protected (link) that does the job.

Aleksei Poliakov
  • 1,322
  • 1
  • 14
  • 27