14

The private modifier is used to restrict access outside the class, but using reflection other classes can access private method and fields. So I am wondering how we can restrict accessibility if it is part of requirement.

  • 2
    Low trust code cannot use private reflection (at least not on other assemblies, I forgot the details). Full trust code can simply use pointers to bypass any restrictions within the process. – CodesInChaos Sep 13 '16 at 9:39
  • 55
    Private access modifiers mainly exist to tell programmers "don't use this from outside the class, and if you really do, don't complain if the next version breaks your code" not as strictly enforced security feature. – CodesInChaos Sep 13 '16 at 9:41
  • 6
  • 4
    Users can also just patch your code to do whatever they want. With a partial exception for DRM (which is not powerful enough to provide enduring protection), anyone who has access to your application (binaries or source code) can do anything with it. – Brian Sep 13 '16 at 13:13
  • 6
    Isn't this a language specific question? Reflection operates differently in different languages. I'm wondering if this question should have a tag for Java or something else. – Wayne Conrad Sep 14 '16 at 0:39
54

The purpose of access modifiers is to inform developers writing code about what is the public interface of a class. They are not in any way a security measure and they do not literally hide or secure any information.

  • 33
    This is not universally true. Quoting Eric Lippert, "Access modifiers in the CLR are security features. The rules for access are thoroughly conflated with the security and type safety systems. " In C#, Reflection is only available to code running under full trust. This does not (and cannot) apply to malicious users of the system who are running the code. However, it does apply to malicious plug-ins. – Brian Sep 13 '16 at 13:08
  • 5
    @Brian Where the issue Brian mentions is relevant is when a system allows third-party code to run on without fully trusting it. Examples include browser sand-boxes (e.g. the much hated applet), google app engine and Azure. It would be really stupid for Azure to allow untrusted code to explore the details of the platform's core libraries. – JimmyJames Sep 13 '16 at 14:08
  • 3
    @Brian That's not 100% correct - there are some reflection operations you can do in partially trusted code; it just doesn't allow you to do things like accessing private fields. – Luaan Sep 13 '16 at 14:46
  • 1
    @Brian Until someone finds a vulnerability or social engineering that allows them to bypass the restrictions. There is no point in trying to use them that way. That is not their primary purpose. – jpmc26 Sep 14 '16 at 16:18
31

To quote Herb Sutter on class access rights:

"The issue here is of protecting against Murphy vs. protecting against Machiavelli... that is, protecting against accidental misuse (which the language does very well) vs. protecting against deliberate abuse (which is effectively impossible). In the end, if a programmer wants badly enough to subvert the system, he'll find a way"

  • 2
    There are times where you need to sandbox untrusted code, but that is a daunting task. Protecting against error (Murphy) is the far more common case. – Paul Draper Sep 13 '16 at 21:00
  • #define private public (ignoring that it is actually Undefined Behavior) and voila I have full access from outside to the restricted part of your classes. – bolov Sep 14 '16 at 11:40
  • Protecting against deliberate abuse may be theoretically impossible but it is effectively possible, by making abuse sufficiently difficult that it happens very rarely. It's important to be clear about that. Otherwise software could not be used at all in situations such as life-critical medical devices. – MarkJ Sep 14 '16 at 12:16
  • @MarkJ. Herb Sutter's remark is about deliberate abuse by the developer who wrote the class in the first place and perhaps his team-mates. I don't think there is a way to prevent that sort of abuse by language features. – Nemanja Trifunovic Sep 14 '16 at 12:22
  • @bolov that stunt is language dependent I think. While C/C++ preprocessors would probably let you get away with that, anything without them would probably give a "can't use reserved words in a #define" error. – Dan Neely Sep 14 '16 at 15:59
9

No, this is actually an important advantage. Simply because some developer didn't consider that anyone would need access to some piece of internal state doesn't mean that no legitimate use case will ever turn up. In these cases, using Reflection to perform surgery on an object can be a last resort. I've had to use this technique more than once.

  • In other words, it is a way of circumventing a likely broken API - whether due to incomplete requirements or incomplete implementation. – Kuba Ober Sep 21 '16 at 20:43
4

You restrict accessibility even more by going up one more level: the execution environment.

Not all languages have this concept, but at least with Java you can use a security manager that forbids making private fields accessible. You could manually install the security manager at runtime, or add a security policy in a jar file which is then sealed to prevent modification.

More information on doing this in Java: Reflection Security

3

What reflection are you talking about?

In many reflection systems, circumventing encapsulation is an explicit capability that your code needs to obtain, and doesn't have by default.

If you are concerned about encapsulation, the simple solution is to just not use a reflection system that doesn't preserve it.

3

In Python, there are no access modifiers. The convention is to prefix by an underscore the methods and variables which are not expected to be accessed from outside of the class. Does it technically prevent you from accessing such field from a third-party class? Not at all; but if you do, you're on your own and you take the risk of breaking something, without being able to blame the other class.

In C#, access modifiers exist, but they are yet only a convention—one which is enforced by a compiler, but still a convention. This means that technically, one can still access and change private variables, either through Reflection or by tampering directly the memory (like game trainers do). The consequence is exactly the same: if the variables of your class are changed through Reflection from another class, or through memory tampering by another application, and it breaks something in your class, it's not your fault.

Note that this, obviously, creates security issues where a third-party can access your data; something which leads to encrypted variants of a string and similar data structures. But protecting your code from such usage is more related OS and code-level access restrictions, and has nothing to do with Reflection per se.

  • 2
    Note that in C#, only fully trusted code can reflect private members. Writing directly to process memory still works, but is harder than in native code. – Luaan Sep 13 '16 at 14:47

protected by gnat Sep 14 '16 at 15:33

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.