Does Reflection Breaks the Idea of Private Methods, Because Private Methods Can Be Access Outside of the Class

Does reflection breaks the idea of private methods, because private methods can be access outside of the class?

do we use private methods only for program logic and not for program security?

It is not clear what you mean by "program security". Security cannot be discussed in a vacuum; what resources are you thinking of protecting against what threats?

The CLR code access security system is intended to protect resources of user data from the threat of hostile partially trusted code running on the user's machine.

The relationship between reflection, access control and security in the CLR is therefore complicated. Briefly and not entirely accurately, the rules are these:

  • full trust means full trust. Fully trusted code can access every single bit of memory in the process. That includes private fields.

  • The ability to reflect on privates in partial trust is controlled by a permission; if it is not granted then partial trust code may not do reflection on privates.

See http://blogs.msdn.com/b/shawnfa/archive/2006/09/29/777047.aspx for details.

  • The desktop CLR supports a mode called "restricted skip visibility" in which the rules for how reflection and the security system interact are slightly different. Basically,
    partially trusted code that has the right to use private reflection may access a private field via reflection if the partially trusted code is accessing a private field from a type that comes from an assembly with equal or less trust.

See

http://blogs.msdn.com/b/shawnfa/archive/2006/10/05/using-lightweight-codegen-from-partial-trust.aspx

for details

The executive summary is: you can lock partially trusted code down sufficiently that it is not able to use reflection to look at private stuff. You cannot lock down full trust code; that's why it's called "full trust". If you want to restrict it then don't trust it.

So: does making a field private protect it from the threat of low trust code attempting to read it, and thereby steal user's data? Yes. Does it protect it from the threat of high trust code reading it? No. If the code is both trusted by the user and hostile to the user then the user has a big problem. They should not have trusted that code.

Note that for example, making a field private does not protect a secret in your code from a user who has your code and is hostile to you. The security system protects good users from evil code. It doesn't protect good code from evil users. If you want to make something private to keep it from a user then you are on a fool's errand. If you want to make it private to keep a secret from evil hackers who have lured the user into running hostile low-trust code then that is a good technique.

Are private methods really safe?

It depends on what you mean by "safe". If you're running with a security manager that allows this sort of thing, then yes, you can do all kinds of nasty things with reflection. But then in that kind of environment the library can probably just be modified to make the method public anyway.

Access control is effectively "advisory" in an environment like that - you're effectively trusting the code to play nicely. If you don't trust the code you're running, you should use a more restrictive security manager.

Can I override a private method in Java?

Private methods are not inherited and cannot be overridden in any way. Whoever told you you can do it with reflection was either lying or talking about something else.

However, you can access the private method getInt of whatever subclass is invoking printInt like so:

public void printInt() throws Exception {
Class<? extends SuperClass> clazz = getClass();
System.out.println("I am " + clazz + ". The int is " +
clazz.getMethod("getInt").invoke(this) );
}

This will have the effect of the subclass' getInt method being called from the superclass' printInt.
Of course, now this will fail if the subclass doesn't declare a getInt, so you have to add a check to be able to handle "normal" subclasses that don't try to "override" a private method:

public void printInt() throws Exception {
Class<? extends SuperClass> clazz = getClass();

// Use superclass method by default
Method theGetInt = SuperClass.class.getDeclaredMethod("getInt");

// Look for a subclass method
Class<?> classWithGetInt = clazz;
OUTER: while( classWithGetInt != SuperClass.class ){

for( Method method : classWithGetInt.getDeclaredMethods() )
if( method.getName().equals("getInt") && method.getParameterTypes().length == 0 ){
theGetInt = method;
break OUTER;
}

// Check superclass if not found
classWithGetInt = classWithGetInt.getSuperclass();
}

System.out.println("I am " + classWithGetInt + ". The int is " + theGetInt.invoke(this) );
}

You still have to change superclass code to make this work, and since you have to change superclass code, you should just change the access modifier on getInt to protected instead of doing reflection hack-arounds.

Why can reflection access protected/private member of class in C#?

This is necessary for scenarios such as remoting, serialization, materialization, etc. You shouldn't use it blindly, but note that these facilities have always been available in any system (essentially, by addressing the memory directly). Reflection simply formalises it, and places controls and checks in the way - which you aren't seeing because you are presumably running at "full trust", so you are already stronger than the system that is being protected.

If you try this in partial trust, you'll see much more control over the internal state.

Is it an anti-pattern?

Only if your code uses it inappropriately. For example, consider the following (valid for a WCF data-contract):

[DataMember]
private int foo;

public int Foo { get {return foo;} set {foo = value;} }

Is it incorrect for WCF to support this? I suspect not... there are multiple scenarios where you want to serialize something that isn't part of the public API, without having a separate DTO. Likewise, LINQ-to-SQL will materialize into private members if you so elect.

No Private Setter for Fields - Unit Testing Legacy Code

You can use reflection for that. It is bad, because it allows you to use private methods or fields outside the owning class, breaking the encapsulation. But testing is a use case where it makes sense.

You can access you private field from your test class the following way :

MyClass myClass = new MyClass();
Field field = MyClass.class.getDeclaredField("usedThing");
field.setAccessible(true); // to allow the access for a private field
field.set(myClass, myMock);

Call private methods and private properties from outside a class in PHP

Just make the method public. But if you want to get tricky you can try this (PHP 5.3):

class LockedGate
{
private function open()
{
return 'how did you get in here?!!';
}
}

$object = new LockedGate();
$reflector = new ReflectionObject($object);
$method = $reflector->getMethod('open');
$method->setAccessible(true);
echo $method->invoke($object);

Unused private methods, private fields and local variables

I love reflection myself, but to put it in a few words: it can be a nightmare. Keep java reflection to a very controlable (that is, stateless, no global/external variable usage) and minimal scope.

What to look for?

To find private fields and methods turned public, look for Field#setAccessible() and Method#setAccessible(), such as the examples below:

Field privateNameField = Person.class.getDeclaredField("name");
privateNameField.setAccessible(true);

Method privatePersonMethod = Person.class.getDeclaredMethod("personMeth", null);
privatePersonMethod.setAccessible(true);

So, setAccessible() will get you some smoke, but getDeclaredField() and getDeclaredMethod() are really where the fields are accessed (what really makes the fire).

Pay special attention to the values used in them, specially if they are variables (they probably will be), as they are what determine the field accessed.

Do a plain text search

Also, doing a plain text search for the field/method name on the whole project folder is very useful. I'd say, if you are not sure, don't delete before doing a full text search.

If you have many other projects that depend on this one you are trying to change; and if you weren't (or didn't know) the guy who planted those (bombs), I'd let it go. Only would change if really really needed to. The best action would be to get them one by one when you need to make a change to a code around it.

Ah, and, if you have them, running tests with code coverage can also help you big time in spotting unused code.

How (much) 'private' our C# class members are?

You cannot. Access modifiers are there to provide encapsulation for object orientated programming, not for runtime security.

If you need security, you will need to use higher level features.

  • Obfuscate your code
  • Limit who can call your methods

If we can access private data members using Accessors than why cant we access private methods?

You can access private method via public method. This is sometimes used to wrap complicated private method and expose simpler, public API.

class Delegator {

private void doPrivateStuff(int param) { ... }

public void doStuffOnce() {
doPrivateStuff(1);
}

public void doStuffIfConditionIsMet() {
if(condition) {
doPrivateStuff(1);
}
}
}

You can also access private methods using reflection.
http://tutorials.jenkov.com/java-reflection/private-fields-and-methods.html

Any way to Invoke a private method?

You can invoke private method with reflection. Modifying the last bit of the posted code:

Method method = object.getClass().getDeclaredMethod(methodName);
method.setAccessible(true);
Object r = method.invoke(object);

There are a couple of caveats. First, getDeclaredMethod will only find method declared in the current Class, not inherited from supertypes. So, traverse up the concrete class hierarchy if necessary. Second, a SecurityManager can prevent use of the setAccessible method. So, it may need to run as a PrivilegedAction (using AccessController or Subject).



Related Topics



Leave a reply



Submit