Wednesday, September 15, 2004 10:55 AM bart

Private attribute's privacy

Some time ago I received this question via e-mail from somebody who started on the self-learning process of developing in .NET (and came across the System.Reflection namespace). Via my blog I'd like to share the question/answer with you.

Question (paraphrased and translated): I started to learn the basics of OO-development and the reason to keep attributes private to hide sensitive data and to estabish the goal of encapsulation etc etc. This is why .NET has properties, right? However, when I took a look at the System.Reflection namespace I saw that it's possible to retrieve the private attributes of an object that way. Why is this? Is this is bug?

My summary: Why does reflection break the privacy of private members (not only attributes)?

The answer:

First of all you have to define the word "secret" in more detail. What they mean with "protecting secret data" is to hide fields that should not be changed directly by the users (i.e. other classes) of that particular class. A class should expose only the basic functionality of it to the outside world (compare with a car, you don't need to know the internal kitchen of a car in order to use it). Properties are indeed a way to do this and often the get and set part of it is just one line ("return _privatemember;" and "_privatemember = value;" respectively). However, this is not the only reason why properties were introduced: properties simplify the syntax (compared to the getX(), setX() approach in Java) and you can of course change the get/set on a later point in time to incorporate data validation etc (important from a security perspective: "all input is evil"). To come back to the discussion of "secret". The word "secret" over here thus means "hidden data which is not directly accessible", "data that keeps the internal state of the object" and has little to do with storing secrets (such as passwords which should never stay in memory for a long time). This second meaning of secret is the one that is linked to encryption and data protection and has little to do with OO.

Now, why is private data not competely private? There are several reasons for this but I'll mention only a few (which are most applicable in my opinion):

  • The .NET Framework uses this itself in the definition of the base class for structs (System.ValueType) in order to check the attributes of two structs for equality with the attributes of another struct (pair-based) as a default implementation for "Equals". The same holds for the "GetHashCode" implementation over there. You can see this yourself if you don't believe me, but I'll just say one word "mscorlib.dll". .NET folks know what I mean :-)
  • Tools can use this information at runtime as a debugging aid by introspecting the internal state of an object (e.g. when you write a "test"-class for unit testing that should test another (already compiled) class without affecting the original class).

It's indeed true that people can misuse this as well to mess around in the internal kitchen of the instance but that's just breaking all the laws of "class usage in normal development". As I said before, the private attributes should never contain sensitive data. Using reflection nothing is safe from introspection (all kind of defined structures can be made visible and can be manipulated at runtime). The need to hold secret information inside the attributes of a class instance should raise the warning "possibly something is wrong with my class design and/or architecture". E.g. password-checking capabilities should never retrieve a password and keep it in memory in order to compare it. Instead, hashed values should be compared, or the call should be escalated to another level (e.g. by calling the Win32 API to do impersonation, password checks, etc; or by using System.DirectoryServices to authenticate against AD). These methods are proven to be secure, so don't reinvent the wheel on the field of security (and any other field: if a - checked and approved - working solution for the problem already exists, try to reuse it).

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Filed under:

Comments

No Comments